#include <bsl_err.h>
#include <bsl_sal.h>
#include <crypt_algid.h>
#include <crypt_eal_pkey.h>
#include <crypt_eal_provider.h>
#include <crypt_errno.h>
#include <crypt_dh.h>
#include <crypt_params_key.h>
#include <securec.h>

#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <cmocka.h>

#include "helper.h"

#define GROUP_TEST_MAX                 100
#define UINT8_MAX_NUM                  255
#define CRYPT_EAL_PKEY_KEYMGMT_OPERATE 0

typedef struct {
    char *p;
    char *g;
    char *q;
    char *prv1;
    char *pub1;
    char *prv2;
    char *pub2;
    char *share;
} CRYPT_Dh_Test;

typedef struct {
    char *p;
    char *g;
    char *q;
} CRYPT_Dh_TestPara;

typedef struct {
    int32_t id;
    char *key;
} CRYPT_Dh_TestCmp;

typedef struct {
    int32_t keyBits;
    char *p;
    char *g;
    char *q;
} CRYPT_Dh_TestGetKeyBits;

static void Set_DH_Para(CRYPT_EAL_PkeyPara *para, uint8_t *p, uint8_t *q, uint8_t *g, uint32_t pLen, uint32_t qLen,
                        uint32_t gLen)
{
    para->id = CRYPT_PKEY_DH;
    para->para.dhPara.p = p;
    para->para.dhPara.q = q;
    para->para.dhPara.g = g;
    para->para.dhPara.pLen = pLen;
    para->para.dhPara.qLen = qLen;
    para->para.dhPara.gLen = gLen;
}

static void Set_DH_Prv(CRYPT_EAL_PkeyPrv *prv, uint8_t *key, uint32_t keyLen)
{
    prv->id = CRYPT_PKEY_DH;
    prv->key.dhPrv.data = key;
    prv->key.dhPrv.len = keyLen;
}

static void Set_DH_Pub(CRYPT_EAL_PkeyPub *pub, uint8_t *key, uint32_t keyLen)
{
    pub->id = CRYPT_PKEY_DH;
    pub->key.dhPub.data = key;
    pub->key.dhPub.len = keyLen;
}

static CRYPT_EAL_LibCtx *CreateLoadLibCtx()
{
    CRYPT_EAL_LibCtx *libctx = CRYPT_EAL_LibCtxNew();
    assert_non_null(libctx);
    assert_int_equal(CRYPT_EAL_ProviderSetLoadPath(libctx, "../../build"), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_ProviderLoad(libctx, BSL_SAL_LIB_FMT_LIBSO, "kae_provider", NULL, NULL), CRYPT_SUCCESS);
    return libctx;
}

static void SDV_KAE_DH_PROVIDER_LOAD(void **state)
{
    (void)state;
    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_FUNC_TC001_VEC[] =
    {
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "3abef2371deeb26adfd40c1788b514c5f420eb09fa5e1bc0f9a552b1",
         "6088cd6a9308c4418d17f3c2764c5ac98d62c5655a3128b6bd2d81a6f2937347ad8d8dc6d01ca6a231bee08c187261ca963470e0cce76c14cf05e9b7b391642ae9d5c5cfe99d49d352d5f8e772815355800550c76c1072098216183e580f973c1aca1244a3a0cdd322ef6a70bb3d9d6067b8405191c7c217e11e47eee85adee1ef73b4aa565233eb323da013b9fa00b0664de3aa289ff70fc6339ef2b94ecd2bdba9017e9503b149559348d1cf461f41e8a12937157b71b14b7e514f907d07e95496874b559ce25eb6c6318b4ba050ffaa521b8b8233ce5c93cf0c2aafd4a59b27268f943feabc81e15daee6ac847036cc962d28b4d1d40f3968c695432881bd", "6f01b4a219e081b50f856aebc011e41680692e805a498df408960dba", "e796a148656a2b391a6f81dd7f83ad4a3a72f629a87fad6ec9f4616e0ae0b3de34cfb0640c0c92c1e8d845c517258bebcc9d8ae7fdd77dc72c6edc0ee05c2561294c0ef50ab90ba3b740bac32c9a2df17294f22bf5fea474e7ff48daea6abf48dba6f6c7562a6ddfaaf9c2146d3ae2f1de8b9e68092ad76caa767a2c96975fc8b1a88e8848eb089c438d5f932d633e79da19808fa3a1e411ad260565c4954ad32bb0d94b0b746f5266241928f3f0a4441f318700d9e93c6d0f7d57e883eb8b373f4e7893285967028e9e09c774344c05418d6359236fb092f2e3a454483656817317abf309cd7f8016c501133bb8b40875a0ff3b04580abe4d4e717151105bd2",
         "b5f47d4a7dabd5e69c2890df50c0cd6f4ab9568fc66779381fae5385b80d7577d5eae00f307ab39b7efc68f885c365e19f0a30c65ecb46b95fd08e0ebeac55d3d012b9f70294a268a254069574fb07a31625077b720cc1b943ab205e7a29e3dbefaa4701a5afbb05e3d90ffe7c5f1b9ca9ad77d14a7d4448d7b7f552ec18aba47dc034a8268b0438cc2ee4f1dad9f08000bf371dffeb8be77a7521e786add03144be775ce1c3425a62226b1aacef10476e6936b831828d9c545ddd9d6c4e76861ba1825deff55d4bd3b0c4a9a938fdef3adbbea48206902b5665b9bed6b7c12eb5fd8c0b6da425654b41235d7852e139073bfb2cb7dce01294eec20f85847cac"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff", "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "13309c3a9d824a4fb0e6c103bcf33504e98a4e52474a62a28e68269e",
         "4ede61e9c7444400fcacf1d91e4a6d1bdbb68166668a60b2f54593ee9cd9861cae788e0d8c1deb8e109f4f051cc339477acc08b77d5540bbbeb290dbe1f560b6c4d35223a8ffea34d91c5075e11e2439f58ba2ef606347588250ecfc909e27d8b43c4d8765e51ee9a147fdcf829062dfe99b342e0e3a253561ea6107236760b7334b46749aa85e96493f5c1e1e52177840aaedcb64b98987571154095130ceb249de8f2410e6ab511273b02dbf733bdb8134d5a19a28690b38ba8e0802cf9414d28c1db4864a5c65876aa364aa80dae00df7ecd01fa2089f1dcd843a9f6d87dd018dfdb171e7d5b4e67d0e9d8564019367bf726ce21f08aa52bf0bdd619523f7",
         "2cefac774b820ffff233f843981f00feb396095bc4dc6462398d5251",
         "97dffa91e261f7d56ce9d3cf014de4fe76f101ab02c63966cf2a4aaeb26f8c5006d4a9c664c472c24c683b26852a8dc89fcc517261ada6f365bc625f2e5d223e6f6e81ce451a97143e6d8c5c6db5ca62af32a6eb178ac027504c03f96f5c5448ee527ad639dd4e54de239ac9e2104672af2b0884ef951cc0b50a5af225457cb7364d90dcbc0e357d46309203a387769ca6dc24903bf108d01d975546405863e0d1ff61460e158254fd4af495badffc167742df5be8c8228fe038fea95342f762769cddb74b109f90d60b2a5e2a17c791ad3ea71fb48f064e1a0ae1f901953294394a7cd54a08de0ae52c9c0805c0d862c830c60d4ac66551e5dbdcbb439de29e",
         "9731a340d8511a83cfee6497b5bb9cc089678e0be85df16b4afb36bc597a949f8bf49941f3cd514faba6a2cf41928ed87b4aafd4d0febc3774c868e02e0bbf644c2f675573a048583babfb4eb11d41921d392c4f10bd81f096af9510a76eeab652fede4ba4288e876122e265aa7f9415830f8274958f106d24246b488cd0d80ad117bc631d800db5e059db630769a86f99e87d483006358a6faeb44a8e1646d7e9c44a60d8d8a1a36106f01484fa3da93b56e4145c7f156ce848939f79069cbef22bb52df7008adb32880d4da2e803fce901498d8cdcb7fc317ab129ea1a743870b82ab4c5b5acb20dbd4e7f0dbda93ca5faa84aeb556237d25fe56ee21d6b5d"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "4cf95a7305b4b0d1b2965dd137731cefed71767b0fd5f1f73a0d6f6e",
         "c8166918575aca44e2192e03aa3da5cc2466e8da2d0ccd515491772347f9e09f3ba11d674873f3bd327f7cdb834ac201b20a3063bfdff79ecc784cf94935faa820238ccd30192d6494184106f1e4ad98ba1edea220743de1e9a4ae9fd79cc1063d6eee36d9519078edcd1ad0a7c2527621db5c89c2054e76a9378e614b6c7ea9330b42f0556f53bd17faf708072083e745b3bee24c1a22cb5df9af0436d52b7dbf0a943353c501498445b5ed372c42fdd236505059384489f6dee70522426f8395df885ec5accd61a357727584aa336b6abf2737263561fb0c76935de661213a307da11a319cc7c5c2a8466c25c4d19bc10ce4d0f7b51c9fdfe58f4a24db28a9", "288a4a953c0d9a34fc2059e8e209af977bb112c476561b76b4a98ec2", "9ac9fb7e09dc14faeb67b708cfc9b9dec878e796f24258247e49e6966ef06804378168ec266edfae99b7a09f4545c71a2ff5a054a2b9fdfb1713b4f8021c52f90d0a68a6a364d15a22644f6ac8434d3da9d0e8a80b3fffd040d09ae8b51a8193fd990372aaaed8fcc322884aacf1e1d9625126dae5f78b970e4bd182208fe89295f85f31566403a989c224b1bb20fceef3fab1e160f88de6e34f01289b65dddc27d79d5e9821e1e7dec731ec5f5f51d685d5c30ea8b55edd618d162d2e67160fdbd379bd280284a8b060be3fdf8609ceb1974ad2a0e55062b4db3abf4f873f523c73f2bf8aca4c812d05a3e0790a7421e01b430b88a63a26379035f6aa9175e5", "68ad9aa3a839e457b9ddf0db8ec81c2395697e1aa7164fe3e707912af0dfefd16fb94d92cfaf932594e3bde79e1104ef7466cd85eac97f4903226fd980393cdceabaf56ed5fbd401a6db09cc227d3b1cefe0b121316d4014fbe2bae71bda7c07b48285d840e6bbbfef8a21220f3a9757191353d4c6801321261981fd1b70d4f4826f178a9bdf7db7dc6477cb29ea52af2080e24913069fe1e2b0eb118b745f8a93a6c039ff4d6d4e0fc53c4f597b4a204865c0ef36087e74231519df1fa7b58c89b236c65c92148635ca00f0e474cb7b37146d7ef0f1398459abfbeee246c3e52a91f3c5b1019b60c7ab087564ef5c7c5219aa2dcd1e31b5c6d36693b6690e25"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "24509fb497f7d8abaf56f01706d516e66ebfbc8a206754d9fd45443a",
         "d39379dab9986259bf17ed6b70b049c2765228584cd760d5ca50d09423e1d041f15697a9c392dca3f39b96f3a3c0f6ca14dd77ba74f006ccb89fefc588a8a894fabb421b6cdadc39f4f2dd41709537dbe72c2770624cda2692fa330401d6bb19695a811100a4b8604c6108b307b3d05c414b74ac3d1eda7fd3fe110d3c5d97b27c480a838163c6e2ae564b067c551e0c0ce03685176a7ae97d8b5d4d53b1f1d8b0004a2cf88502f97d42bf7c4991a05d4b54579772a040e30cd7115828eaaeb6905cccbedbfc2c3563ff2099a55ac6eb5df321de20dd047721974c3d0aa2d015853601f07c83ce91c4035303431f38a8b6a40b828faaaabaf81e859eda7d8089",
         "870e101989d9da4960d25fa194701ade55136dca732958c26433ccc8",
         "1c64339bd3c6ba960643ce14ac8922a26a9ec2c12b459ccf6556e990b2749b9035be152cefadfdcced660d8cd369111bd62d14756e4bd4391dd6814d7e0dcc66dd3c42b29e3f3d58f23222bca5e35e527f97e7ed84df9f2addd3754176bc2ab5f5c3b41f0fda53b844367f98f8c96b8f2a25b8370c0a4dee9f8ed9b300e55bb328d0e7937b404798c7f9f783a533b12401601cf65c79af9a9f7b1c5169f23bf3a6807e173758640cb7db1327a7118d4634e5c7065aa9e24ee018566a880106337e188bfca782f2c5af12293c145b6d7253e55f415f7a613ab22ce6387b4192ae1204eb03632ab7a908d3d27a6232ac1a519ac15d4b03bd1520be94c429bbbf2b", "66d69ba1f73ebb23790a7d575d4ba1765f67421d8f92c73fe57000c491863d1f752121c705b3be816ed9de9dbb30e4a942890edbc2ad095c248df8fc5230f2b382831b8e2d6aa6784fa7a7a2a2fd960819856531158fa1c680066b6d151d8bdda74f5ea0c1b39748b25256a239f664e1c5c9b098f389e1365309dc995d7d761bb1129794a916d99b3ec266375d834f6ccefd4e58cf46ce2c7a481506fa3de6f67eed3e7cc8b2df88813d39fe744f9aadad18f88baf959f7b0428f4560453d048fd450cb9b41b7d2328227aa2fc371de1c81c0663d6b542de10f4c1bf5f99369f73dfb7de53fbc153cb7d24358ff392dd954dca5eb0527aeb36998eed7b97fb82"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "991b062bd3d604203eeba196d94642150c07e9ea17ebe6b571f5bc9e",
         "93e4cb6d5f2fa98600ca6e99d2e1882f8fcbe55adc15bdc71df925427f1b832b80e545abd9022b65fe691846c1cc0400bd13e54aacde58f1067c73d67fb252b4d789acd65d899ffeb6fb32e9ec6e0de882f108345fd2c653c1d212e84d78937360a2da6f3bff24ffd5f30915dfaae84ba91b17e9dafd9bbe39a56cc53c932ad72fb7dd45538bc9e4faf13b21843e04d5dc86681db97d6b9cd83c6d39c8c67cf9385ae05c55f3669f7fee7f18736b7fb6a1d8ff55210485f777d7ef5aca6c5af3e2a2f2975e5c9f9ecad22f88181bbf77f16e8c45bfe7934fc81a554295c6fbd18d2e5b7cf3370b746a17a1010c3f1466594649bce01a13f805a36d24dd7bc7c6",
         "77227c7376005860f62b3d1269e339f0f62f3a57efedb5636835d613",
         "5cdf1e3247c60fc224eacfdc5a6753224d029eb0680a4cf855e4da86b0d92efd3fe59292871cd16fee4afa89d525b40218d4971241297a9e1f2490b58fa0d6c746e2e324a0855dc7fffdc30dc1704e946f143ffa208ead22496482faeef5649546d7e82412f3e7e590a60832c2ba44f359aa2ffcdf6e9201037353346052ffe5f8532c9b3b0bebd0bf03247f07c3cff5167aeb7e8d842cb810f15f62a3460aeafa63c208e4189acfdb3ea3f9476a8df1dbe9cc2265f41c78c6a7fe02708313fe151f0e38a70cead01cfc1df1c54975f97ab21e2f0b09582034e9799e04f42aea04c2f496ddc2b1ff4bae0c4a84e1468c15e4b0a2fe8f7d7bbb553a00eafddb19",
         "66257222d2cc3a25f7f5a6174fb11362875e74aba8d342a782dd981f677bc9d4f98387c835c3de999f80b077866098c7939d58f1253a76f9f92dae298b42ff60c7e5e03bc685458d5637b17f6f8f80710ea3887061d621fe18ad7335f31aa4d87eee568d90c3c1c4924136152ac166e13cb4c56ee19d2b0f4acd6930cfcdaca23be49781e88d28d6e172f656b08fb4f32303b60ff8bd8b7b61d4e22e427e1fb9498123285535effd9c74af7af7fc6fb431013363be8b85627a51edf45470fd369ea7300156dac3465ede79f91c0f0c2c3563f1e151b20567c97aac3033e55068f91afaa0f39f84436c179c5c2f27588b982c5c9dfeb3675bdd600c46a736a997"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d", "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff", "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b", "90304ebe3fe2cfc052fa7a8e8907c9d53b9c95fee2a7934ccabd15bd",
         "d9bda4c8d4d7d678ed57d5fa534ebe302a1537ca1006b6b271a9ed76feff75baf70b162724ac53a7282b59c7ba4e03efb0b8c2112f8e5b7af6f9ddb40d67b065db9576c6fad05db4dd4ebd66fb9b61ac26c9118ea919faf4ab1e956759d149ea809fed69200bff850f3fc94498956ba5e84cd091925b0e8b0495bfbf0fbfec14b52512809a675bd7982a19f3a9bd9791fb23934adbd2625789a53f3baca53dc71837c7f949d7dd37f1ee61fa2a6910df7674db49f48e3725f7a6828270d89b75716f6ad1831008e405c547ee218c38816f253bf773ad046389516bdae7e440026a02bf42c56c22323ab6fdeeee8cd8ba9cd01e096aab87bd264c6499e5640bad",
         "48561d8c5f969cb0b70c037d119bbdd339e900bc075d82e54a3a2187",
         "c65d07a6ede99c32713b8b20a2f29b52c81a3c68c0230a190836b7a129c35f79c0ecf70787846bd36f7ea910498b94bbe2a1e47fadca535ab4ec26e41de4f43dde4430598638054b08cf547009c8fb780695133a1f424c885cce914efcc3bb81d4cc97b2ab44f1bf1824639f264d6647cb3a5aeedf6f743ea768c1a96a01376f64c251fd9669c9a64dd330020bd15039f9bb68666b646e1fd1f1d24f7b214043140968b66fe2ccec9c653584dc8adbaabdf232a86dcf7fc9f675b35fe0689768a88614af3ef8e0b18ee5e50c8575aa62f1af5bd17f34d133f13bf4e7dc7eaed212ac6760946a0163caddabad68d3dd9561c0f66ccd75068d50bc93a642c6dd53",
         "b288765f0c306ad3f439f0eff63667795c53929bcb885ec61522d6caa8f43fb86f135dfe6efd0357a738802af8b87bce442c8673d4dab0dcf28c005aee821d17b281fe7d7376c7b0a7c634d53f06b67acc9795baeee72cf95fad97ff4dc6b6454f0af157fc9ad5b5aa8e21cda68c90fa0839c3dcc1dd51550b7c926f455ae663f97fff135376dedf0fd22c2d4366c474c03e1a559f3858c35b3f01e7f53b7456c7efeef2abc039cf97a4fbed6e144de09f9d1426bf76cf1b17f3195acde1d40f59be6e126a87c59a414afb392b1f8af6d78b0dd8c598bad5a55a5dcf4660f0a852a43a1a4d4a8f11d91c82ed47b658d03917e88b8dc3cdda938a1f5075634d8e"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d", "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "45e344e143fd629e6dbc9ea3856227e9bc85a05bf204cc076bca0d14", "1e7eeeb1f82425b04fec5268e50f123bb9bcb00c4dd5d154a869f4f0e9cbfc7c3cc2220764a7da885148f0b621a72aff827dca426572d500e22e36cb76eb1db50adfdec678271c4a811b25dbe653801a1ce5f3744a75a3b8a5c3b252f2c70275d3995fad65daca10f6056dea8122ecca1b7ad5814b623e4ab1fbf7254b3b25b8c4a47639d7d3887cc627b4f89291dfdf8d8fb60630b370ebd944d528e44f6682d62f1438a86f5ea339ed511258d230f7b5eeab8263ee6522c98a6bd1261321d05e77dabce970ca062ea199bd3383e89cc61de4057a737207933bf32ea418fab424ba7b608b5d3991833ee5742e9417b11f5f41c9aa420563e9f654ef6b751bf5", "21b48fa77080e8fe23887a8b5539c821c8cfb0023993a145f9380e09", "502c9154b03197a8d992d7c63f3e3e140b00a8bf49d8d3c4e79d0f2a3163bc0f3b73fe6e72b92bfa9abc1d4f9f81190e89383383b709c1352f328c524bd036a54a685fc6e231d9addcc20069e5a972d0372f362285e41a099345ccf7e3460afe2482b0bc41558f7e887b58ceb3ddb9a77d42aaaedac7565d8f4201f338fe87d27b9438058fd342740a30ce776f40266b019acf3ced9b414b842a0322821d171cbfdba711410ce7c3f3a5225344088f9c581033cb382aedbcd964841dece56376495ff1d1525aaf6f46c045ed7719f723d4bff6a3abb030fa7f625e4eb8199692c9a83a9278a294dfdbb1ce3ddc9f33064b5b061704d9fe7478bfe755ddaa1f4d",
         "231073548f845acfffe37aaf04af10ecf4dede34508521ddf8800dbdb637cfaff9ac47870050eb0be7a4cb44173528dc37ca1d696ce227067fc628bb0d8634df38ef8a2aa913d7d72260aac7aa2f8aec0814fba0477e2812d689f785e2ca4e84db29612f95a668c25c9cfb932fc307f63e0fa6ecc7d0778d486cf29c322d12c5afac31b5779d86ed9f696c1b6235a09f6fe29207defd4be2bdfafe9f9f8d5698f8193ca852d49e9dfda293fd5ff872c23e71874bb0b897019ce7e1d6a5e208dccb1b541158c70a5be029283fa26d5a5d311d9f82cf4714782ddeb4bba48f716bc8ca812557e78cb2244e5a1fd98f67e1bbade66efc8c2119db3b090a6d5717f4"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff", "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "4469eca2306b2a9f031f88051a317398b9059e65aa078cbbe116b945",
         "9092b36fd2aedaa947194c14913a28e517aef7be1144668843539c3ebd84449f71088c4d732a61ee49e861f27e9109a5189e9ae006181dbb2d7cd9be730c85e4fb14d03b53a059901fae727bf028a417c8b8185a9f239b4c58fc441014f7d7dacb79adf6870f5f59e22d0a0720829ea90064c6127e073af39b00ce2b6542be74f99ccbe3099c9f277b9b06528b7d74b0f419b30be0c022044daeca0dec0ace309c7fe038ef6f14e7358d5deb5b99e761bdcfddd45eece8933178f0094da3d3bae81b17c65bdcf2d7f735869990d0e403ee241d2789112828d54e12919eba8f0b38ea0e0533d3db38996a6895dd8401779654df0dbd21a37566cdb4e46eb40bbd",
         "bf712a2ffe36c07b028a507c2d13fe7c97a80b89b51d6cea33f138cc",
         "d732c3fca17be8aaa6886119696a244ab7f5609cc8fc5f05f385d0e153a2962aa6fb141aae8ba430506a673654fffb5d5124605e28703b88499aef5f3e38a326e9659e925f2b8747c7dceae7b236cd284aca8f349d61788a906ddc07f6c4232f6349352fd3b1b2776813a5e3b13fb719694c76d1a6e775e10d2296b5c36560e6591e381cc82143f64f0c737295c8420a83045452c610482f77f38fb85e1cd86ec886aa6ea292626ed9b0f14921ede109c8a432d07c6e1b4cd86fe4dd46f765cddf1ab0e6df7ea073828342ae90a2d224a209cc1bd6dc3686a8576f6547cc27dceb8e2edfff25f4ddea180ffc0f6085d585996c52b5dd85099623cbb23d45928b",
         "6727953c8255043c3ee24a62f47438f3a5d5f488722f4da9099e8ce64ee122db9ed710cc0d7bbb033949d9978d3781e29c74f5ca954c89745eca35948c0f674243ba60873caee24c85b48d6a800bbb4378082b719c43b81d3973d3ebd84a0509c0d49976e53e8e56c1ae1aff2c1c051c265f1bf0aeb21f8d3a0ef1eb467bea10c0d2bc9abbfc3c4a14a45d82aa1e71cc85c1ec8623ac78b8dfc8dd4f81cbaaa3ab9b766a50e8993855473449deb819fe5e5f6868b2cd8d77baa4a43a73a6a04d249e721532e8e4e7152729e6e4f5e2dce31ec97d2152d024719b64b3c8607243b837642aa28053b5cbfc3247396adc1ac1d4219f5a58a86b7295f3c99900b4a8"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "70363e2718c887be1ef3c1bfc1acd4f4c78ab32ea2c51b51e7746b1a",
         "0cc2dcf4a923ba4ce99436ea6a3c63411b1e2d391a5a82dadba13ef39e7e1f1e3cd0a81dd84576f5f0f5951cde7cebb907f6ace7f65db051f71c3d6a97bd4465f25f56e809f3185d87ff9c9b7132f09d2f7ea49dc969a3c516a717034fae082550a0ece45f4742dbffe5bf128b28cc3b690cde62da00c73293ad1b61bb1a979728b9cb4751ad69b2422601f2c0f66e28aeefefc0aebc5a22e21ecd6289e369fc8e736eff730cc04d79c846c4e93b7ae8775f074b97e15fd179d78240b97b2798586e9ade0dd23fdb92a5fbbbc7ed7d9f2d9360b52f304d44fdbb08e67c353f2d4944cbb8ab44d0cc2b34e93f39a9f3854f1fbaa1b6356278be9a6e7b5a488675", "1abb6ed18ddc18a0aa6d49e19d0c76076ea22d89173bb57c18f54b6c", "9a0551d93f376d3606e174c9018809d75636a84b0bfe3a08461aa63706aaa79282f39604e26475adace87d4f0ed94e31c2d033aacb957c6d48560b726aa2906a3ed5c65ed4545a449542b55a6c9805aa896b17ac788dbb42c5aa18c7f1dd653678ba84982e96c3044031ec05d4231dd761fb14e9a1be6645c51823cd6c97b4609020e00f07b8ef8eec48b0f1fa609db6374faa59ce3d94c24318bc12e015636c1318586265a66bd6329653d4e4bc2fa971ca0fb057e7064bff5ab05419c3abd11ed2ee2a98918b653bd803c27e446cedaa27341ae6e13f2096eafcc81fe44895ab0caad47c92cf6a279bf2ffcb02932eeb6212dbdce3b0e0990b8ef5a5388506", "e4406cac2d4a3780e37a14603601a502871e490526ae27c697a51e53374f43e27729d2e67e65ade3bded5c811570e84269e266c3be7312f02384839a6b95ee9ca7097baf67cd9fc1a49654166c1e1f5caae1ac69c55e3542ae4e9a3096132ef775a24cf2a71825355c83cd083b2ed145bbbcab7a167b89c472f8ff5696232afe354e7d5b8becfb275182efdc97623f82d273c67f58b46abae854f31f92db248ff3ed7e4311e5a6159f7b796b060b8a0fdf357563b2ac9c50364f7b500f181086a27dd1195aea554fb6b9944a0fd7b68769c879e5337b1f36ffb1b19e09aa6498b83dc04c6e485b421004ac5b9c4bda16282aba58aac6d8656eb6d801177e4f8c"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "5bd7c169c1cc43821db7de4e3c608ae2742d7e842cf5376549bf59c5",
         "d8e8c3d5da328080f421f721b5809a893d21875cc3bffbf5a91bc41b234271b1b617a413dd9a803d70203eea5108a01f0ba50e63107a138815cbe28cb3db9b06b5c7c51833384e2720d5d4ea7decf7d2f67b6fc37f7ca6af2673274b5e7bf8a2c9accac155e6e8e52e07efa32edb85c75a2eb01065c426ee89bc7cbcbeeacdcdfb15e0caa060460a5536c73f435f0fa0d457d40d212385302b5c87523798d2c920e1bf43fcf77ee3e88639a0d2bbd4b33cab791924ab2c350fe4414cd36d404580f43c640dcd7c84740b0c0ecd06e355396328804a6e57abeae9105723aa2170deadce4426a6a9aa520171521456dc9b4ad101e67e2863c1a7c975b02754861c",
         "04d7c47400a38071b46b9c70d641051dccfbb42a26976c81bbb3815f",
         "5c513fa40880ac7895c79d7ddfdee894252bb8d8afa4e53635713554ead12e85caa0a5e15ee671f0055404b0d7b803234cdab70d7c6d7b2b213af413a331b0e4147c0b2ce1d6c21a41cf9276ca497d6caef097c1d15bc2ed0e705b6033869a1bef40ce72d090deed3d116f345570e96d17c41812dbe1ce8f0a88d7609c999739b40bb5c07ce02d5fa5464ff385bb4225300d618949fe22882d78256ae72324ff37db88c16f575925fbb7e4a45918b664fd9186bc52f08f30f9e8ddac7754510f761682fd0141824ed8f3e68f0104faa1084e33e5fedcf3021e9a9713253b81560b3631554f8a7e7a2477aa025a2c1217ad7137af6899a50d5f7d1fc3694da099", "c3287d13a4ea1cc293db801a69c94bae7bc70dfda3c6f8548306278f8581e2e487bce9b46fb42a65b59191f3e71aa2383968e3f2b482a05ac918d62bad2fdc6438e7e475cd676477bde6590edd1124e81c91044dd33da07219341d1387b501c8220677e324408d1dfb289ac0bc2c6f002e8e80c054939de27ef78e607f115982d058f847373cab5c0107c06e663914bc94372a33f12c105d90248d6eee60535e0156fa0d4464941645fd9d440bb2c65a0f343c75ff31e1d03f232ff4ff535446b2e8632e4e1ae873653e1f45d6fd2140260db0e1751202ecde4aae4eaf6c461e350a36dd5dfcdf46a94120066603bae5f2e36b5294c28f7640f967eac5cee35c"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d", "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff", "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b", "088f8a0be8379c396c848a245f464f11581718497b69e1adb36e141d",
         "ab194a6a7eb48212fb4e08a0f0d370f3e10ca65939c0536166c1b692409ce6bb75001c4439097a16389b65ec0061fe1b1c69b8e55e15dab126c1679b4aea6cab378f75237cfe899999f7a9852877950507ae82925a02f7fdd830b2eb514711bf24c56d55a11dcec25cfbef0ac7a0722546fbd401ad803654562f99033c128afcc47b0262cc427af120f6be2895a4dd70f2e7f9cc147ec8ccb73a41f12ca039e98de8153272d1f2535cfb9c6252ffe7b77c4d24a9713b1d1f11411acd0ab73e73c2568d3bb56ad431805470c3155d97224feaea592f23567f6654f1de6b8cba104e00551533c89f77e31b4754f8206899e164faf4355b9807580fd3563ef0f278",
         "37b3ab1ef7364008cc479d5f5e4f6c3f3bdb6a2603c320a718b536bf",
         "72118df889db250dcc1f1c2a30e804b3f4c1664419aa9fefc82b01159140b9e510825c0674cef2fd59057aa3991a474db51dfdf864eb57fdfea5abec8673de75f7f58131ec00752e11a2402574b8dfea62a86218b7a1de729f4a129d3f7ce5990676f39416f48e2c8d1e4292335242ca39ca874f528928861dcc37e522eeec5ad929f76267f6238a528032cd5fc6d72017ab9580180c4b1d52d764776ee8ac9065c11c35d3e0aaac730fd0a90503cdd08e41c806432d60a940aa3decca4594f246e7f2228791ddaaa1456bffb62bd4664ca7be458680fcc5f54289001ae2e2e00f06c83e2c32082d0873a4254652b265b79d0dcf602bea26a168389017e31a01",
         "34f0fe6843209eafbf58a1b89dc57213daaf1a2718ba10934a0799105c8f8f19df9283ad38adeba7646defa6f217bd2c1e220cfe498b995519c0098399b672a98fbdda0516f4c2cd260610b2b04294d9b6c79929171d4ef66a1b0d1c40e5863402808d81b882df0ca76457469028c0c182f07849914b90229b90d6210f5591ac8524e9aab073cd104989d933dbcd1b2bb1e87a3e323e76dc008952668bdef286b70d0cf39866f070727a852068bd35c3dcd70ea84248961aedf0ece434deae9669a846d6eaba399d508108eb175d5b9a4a6d97f0824227cb6316be129128d1343358a8c1359f4a01f7f2faa22122107dfdff91674699635539878a7c4626cc1c"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d", "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b", "6ab353245b6619606694bb36631f6b71a945f523c6548e32f0e3b943", "6f86d0d29a539f35351d06d3cb41d3d4eb786804c77194b44007916ae106583fbae84f4a48a318e4013eeb4c6e8fb79fe96f466305ee5a7fe07137e56861dfeb6519cb1c174ca3193bc0230b97b76cb0fbd8744e0b2c8aa945e709ae6825236bd690e46d3a5cc4a823ae0047c6f8052c2b9362f82746e4515fc28f6dd2d8d35e53c08fdcb57a56f7b68d7edfda1f88c8e52b4ba3dbc7b07028b2ec41f9bcbeab6de0fb31af4950b6a8136fd21445834d544b9a91f7fb006d7bcd6d66789a8958fb24562a16fa91ce6288521d5e7ff5b554685354ac505cdfa1956eb3e1c00c8900df8d2185402db49bc4ffc77ec50ef42ab6b16bdfdef63587e12e876936be9e", "27116f19cabd2165e517906134a3810f036cd03fd8a721f198d41576", "d5a25b7ecb718aaa1b31c69790de4ac35d44ac48a13e6dc7a50fc429efcc5e7fb8d2da0af244304ee51875a91e3ae16e478b21d062aca19f1d5f9f6ad1121e6f91a7cfa1662f064d80ce10a690ec66cdcad48eaed4970cba325c393bd291d5a1fdd0638006880bd91de58a29017c14cd7e2dc6b2d13bbf2265f5cc3c6f7843888f326e884b3ed0b7a7dfb60c0da479b6bb2a8ec9bd56c6b13ee38b26144dd5a7529fdfe2c4dd9234526473db9cfee937631bae812d1de1266f99150048d1beb58af4b09f769be752361c4c2151c927190225eaa72a3a69b12f0ad1e81159cc8fcccb53d56b980c8a49451e99fb5903ab4ccc87c581e6efa7e25d49343f854e79", "551d8ea234c658e54e2b3d55a4102de487aa86a8ac7f754c460cfe4b16112bd88d13362f45775ed290647b94c615d88c0146ab1d92783501ac69b57cc396c734a2158dbbc6c6ca95731d9dfd4cd55a67df3ad29bd603a323cb119f30950737e4bf2d2e8151fa0dfe96dad9884ca1c254b60cff54d79ffa27fa7a0f89c12ad1d43b7130730426798c51e452eb06b37d0f694d2e428774680051b14f8678b5f36d7ed539d16b557ed19b927ed967e6653e4bdfd6d2bf5469f8f68344c8a7c30232a387840ca01f4937516ae4113492faf9c5b15b00139ca736e2ae52d5ce5b88f19feef4fdc7e83ac8c7e780ca2aaeeb0f99c8efe988349c90fe92e5be7661fba8"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d", "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff", "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b", "55becdf81be67fecf78e7f51279e64d04ea548c7f61be2adbfb0b260",
         "b82bc2627c3282e4b467a21ce1be624d82bef26fdd319aa1d4dc7e2995e4c5406d8ab07fbd2b418b41f804033ed40658754643364fec4abb1d71d6ca1e82de0e0e90db751a539d0fad9e987a0d42e635d19d81e0787c933e4e4792b22bdd6645e74ab809217005e17d58e29a0d601492cfb1d7e61359a907ee692f126d4feaf396dd1c8daaf01f31654d42fdc3c6cc23ba2cdca4ab9140ef1c0d797f88b742699a651980eec97d79984367d52b33e4ec144ed16039222d415221128f443ec86d806268ca96785820fc18eb2ebdd192a5fdd0db62fb4de5e719f4f3960cb035aec0c08fc670a131164ce8a37409c4f41f58d74ed0e72c4b99dd6c7a0d7ed29746",
         "815299835ad8ffff127e9c47e054787aeda4891011927030cb06f719",
         "7f1371aa6422dfb85e42ef5968be20cff31134324152e47cf975818e1075bc5539bc8a0d431335d31ed1d1ac7d1663bedd079e46f357a77b1ddf7973508d15914ec5d0379577a205c5d1e42728c0ca6aed68dbe24505d9021451c8f58541d013f0de8db8f676fc1fa246d92f149d956145e4332ece5aac74b4e58c268986db3012cae450edd8f9ccf6810a1b7a7092cd3325aef111701d1e17998532deac77d6736e27726116fd486ebb125b5c891cfa7a945466ea8568f5d82c5053c2f51b4759edb80150a7e1edd384ed5ec206aea9997d925fd6c0b714f59c848fd079ecacbaf44e792d4b8c2e76f24ce3fabfd20c5ace9ad9fb4943217fddb68051f21258",
         "1b432f63044589f5924fe535f2f8214bbc0b1e404d5bd882ed3da0a931cded3b9e73ec977d06024597253d6aa9133c9b6f3b2becfeed2a8c943c98f8e2460745a3c04f01b8351d9b5917ba0a8388365be3229b9ac592c0f5a6ce7459e088d5ed133ef56ec5ada4c53f094029d3c97985943f6c7af824b2191cad3f35841bd7960cfb280ec710392d9ee2181aa3559280a1ae38495d8716c2dfc84d5233606a31dee5e986382915bea9c55e52f4c07f38c9d44b011b50342a4772090421fa5801d9ffe4e146aaa42e9b7af2bf88b9f34e3066950b28d505afead7b0b9d7f8d0c0319375e541460a2d17c23d18670f33c89aa71cdb42a0408c2ce77b6b7510fc81"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d", "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b", "298290645ed01ee2500f0182b2adbc2bb949f4598cceddc4aa5f2e8b", "8237d24972072b9f7288e7f284d0d4b69054457fcb74ea4cdcb294b80fef6742fd0d288562d82718f34995d1980530aad9cd9d8ab2577e0ee67f1bd50d1a07cbb80f4b353bf893b5cd2bd6df70e589013d819680111ea71fdde7a9802df7c61d23aa303cd4b0256be42d99b63f063a4abeb9034b6f2f8f558a5d53c6aad27c39f608943c238e7484bae69fd3d31273a9cfb3492c4befb7906a2692e3b35bb549c6e51e8aed5c4f29e4e6b1a0decbe5aba360c6c60acc82c2a3bb1637af8b8efd37525362e371e49873d9e661ea1a98464a5e4bd20256b41427812f61618eac0a55594f79f314f88dc1fc80a87f91eef9d03816666390d06ceb5e02282338ddf8", "348e08853d7b9f86f8027c789977eea8cbcfad28fd7fb8ce9e3f1a69", "20a5ea5edffc9a5bddaa6dde9053d2032fc9c7e44c6f1d4e9da52c084cf6b8562cc513f73538407a095ff5b3b0df40fc2ba89536a73b48c3b212aa90ac1bba9ebb5da33d5d35637ba744091ba97d7204f82422ef723b20183d8dd02bf5294a2797a811a187e3a5cad0ddeecc3af92f139925a355f737226242cffc74bf4bad64009963e565955a904d16c4338d8efa80c6330474fbed6d40b40e42c4344aa36c6ae4fa1bc3186fa6b1b40cd8b9a8eff0e918c6350b92258f28964121cfeafaea48d89e2e1fc3dd5182422d8663bf0b1cc8d97b920bb65166b94208a048e11e3467061aa98429c9caa34a9f131429c17ce0bfa963d5a86f79f90fdd23301a56ef", "7a1244a1e92eb080ede707ecc7e081c7edea740a8c43fc6968c1cf2ebb6a3bfeb98b7c8b408a2d2de6268e83383fec1cc2032d76d054d37440ce39327beb9d5974875366b974bf01f5a2ec15965e15d3efec98986f7aee4f528c4d7fe23b9ea1d5f4b76a3f2ef5ecf2d4f30d4c82db39c0b09b5041ccce97c09fcb51038736000055f75a21db0a9abfe4ea7d2dbc066653dcf58d81d8eb2eb49fb5dfd3146765bb7878a781db58b06812ea8275a692826cc2dcef06a570d977e9e932725f7505c25d14b45e4e3e33faa6217bd61a0b8e9e60c5d00f04c15813754afb1a33d356530433bdcc6e40edc7da978ecdd14a4dac9ba5caf55bf6ff4a9dd1a2bdabeac2"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "d72a8b812b227a7e0ec1be32fedcdaf4da4ee2e36e73402872f94620b6d4b1dc",
         "b40d9a6860c30f0c2ad3304f4b548126b9ba583ceb7745e110c6faceb9c69155213bea8a86cd5b9fc19f64cc0d66fe332128bc7ffeafd3188c5273b4e7ba505e981eac7db5f12ad95047fb6f1e34aa9dff3120b8550fc571b9349f2339cd96de9c119d0e6be10f690a77c75aedc52a9590c79294f80381aafc343cec6b624d037a6a7c92f72c3884337ef3fdae20b0c660765360f37750960dbc40e499fce579da3b6598fe286868c687bbc8127c1d0b42e9b46cd91b23ba34593b866045b62548537cc7f824b8f671b54298de8c6e617e1bf9ab524f03d1de30b485a73b97da975fbe8ad62e199129b4666d037343be134782208021f23ebc66a607387177e4",
         "641f5aa7c7394af1b21a975dfb692094078eee35cafce0f5605863431a6da681",
         "43888d2ef03e8b1e709fe5803b7f258b785515547151e5a91805344e6f0fbd7cdfe5c21b77404fc70989e635c7215ce5e5116884efe29818bbc0ee95d1858b3c9734d4595dee0ac275b1cee1ad119595666a420ac170b2bdf973671d6772eaaafc8a310422852eb16d1fe2f278dc70f0baddeb5cba5ad7b8c2d7a60fb485bc9da9d35d954d1ce469f211136fa2001d7864a57effb00857891d810b8f36d46847414575d0538eedc46dc991eda739f42a9b7f362717795e586ab95105946429f10f00456771387d65a8923da9969559742bf265b683e001fe65c3ee0598979565b49e8393a761be8a8a5a254d3b391257a7dcf4204d58152aced1ee0be943e211",
         "8ad927defbd51c3f0010486493a6016c91f7b462552a1688e4f6b49747da924cb8eacace8efa194cd563397e0bb5e38b7248992b7fb51579e12ea85061e6688b302e9a5e2e0d61e55ac08b30f7a63276d79e65249a473f3f852b7caadb3ff44d5561b27a24d43f850e2065c39bb8d187fcb6e8c8c37a9f5e8b00fa5e8f33732857d49b591884fa50bf55e24dd0d63a9b586da470dc51509b884956a373d9bb0e0fec33602793d514aba435e8b5bcffc93f32f92b22ed995c54483abf1bf202e97b51eb985c19efb41ad371784494b788f318144e793faab766c9bfadcafcb858a0a4c279539e0d5064fe8e78b70d8e866132d62c35fd779f725a1123596db8c4"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "415952df4fa2a1909150431ba20fa7a09f724de7a043439c215323195fe5527c", "9176a83c753a6c4783d0b693c1d479ac212bafc783a819f804cddb0d72f00ea343bd187081adbdc07b5bd2e10642a3a307a074a863fc4a90e0084b8dc8f02e1e9e9e3886913694d04e4dc189c3a12cf43e618a78937b4da77ea46b323b3e5cc0674950deffcd81782d55230fe7c3e791133da2fae5419cc1b72f61faa7660749694306d4df711dbe2eec2baf45cb2b880f3d5e0592b952b139a621b816c967dd7a2ed510d2719dbd436b275780c96f655786fa91aedebc315db711272e3842f1a5b92ea344021d30c8f6b75c419ce93a23f88e4340aeae0bf36ea4355f0da16d04b1f52881ae1936038a8605d7aad1b67da8329f08825210939a159f66388a1d", "4b0ad36a4fb1844a0d9df59daea1380b8393949102b1f5640d1f2d7b58d28761", "7158105d26ad6edf485444d10bf64fd87983e1b4562c405577a71b3f8ba4897b0d4d06d54c46e5b080efa427b5895fdb47c043e197db47a212ab3651f849dc556ffbbe2637b0d66bbbe021d38428483ce5192de450dd2fbb70bb5551d4989706c2dba6085ff24fdd10aa93c3c07a60d36532b1e73a583622f994adbc111ce47045cc9d00577436427baf7144e50c98918f5920febce91c416f20d354197f2ba618ac16371eb9f455106dd52b5811393ef2a2beb0d2ab9d7be38d9fe47ad9646e2176f257b174db52a8c93a6bb6c31851b0acd83c74ced94c627c09d103889da8ade2679b541ef50b6c3f440ac841169d20f9962117e03d21f835433c7aa38c4e", "815640ff465222b9f5b3773fffd8aa57aca2e71764581f91c35c7719e682781d03c5070887f22f592ee9fafcd3d335e31fd8fce50e8e32d6b85904e264ce7d19d772f74f9abb1ab019441914724994335ed54a9d8bc8273dfd0a263b494c278669d02b9e36fe497698734a685523462f1abefc71b7f8b1dc787d46c59d9b160aff174ab2271ac49604fc98fd5215a3d06d13985f7f11c385230bd3f8bc273d54c17ff7bf2d38aa625d39ba2ab24cf26dbbde2dd09fb3efdf867a99923205179427c815eb6f211e6e3e616607b6bb71ab8519706d2444a88ecdd9d5d89169c797197f611f126c10860089963ddc652e3e36e70c8425634096c1860979fd12c965"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "bb3d973fb0a15ed76a46c0961fd605247cacadcd2c965e59be5846fed243932c", "455340e95e82104dce0009c2b1ec743aacdb11583903e66e80a8c074a683d56b887b6bcd4ae1f09e93315c2e7f63e7e3e645669839a46ac894de22cdf145300eab38846394fa8e5c4d4b3a8d9c27db13ff7876160b804c2c5f7c931c43c02f0a72b78324e479fd0a5fa9c4e044923651ee2ad548a483b73c98e4e806ae979c1fe08d4362ebebbe38ab6e94e2aac5dceef8a6d013c71f91769cc57f7292dc3ebd0be9b289ee742db428896ba09bd033727566eabd8e6ec750f9fc80c88a2d79dc3ce80ede7cc527e630b8e7a09386c1c7fcd21382586853b30e4998880b30798bb4f4ca7a1962820bf7b3af73dc0b74992d09a9a57217d24230e8d10b3099ada3",
         "05404b6f91a4b747746884d23394f3c7788e3e8bdc4d10fb3354b4c615722c71",
         "5fe94a8be8e81fb8a7a3f383a908f3f8b4fcc52712410314002c5f5a92c8201001d7ca1f67599762c3c86e9925b5929c1425696511cf43a62fb3b425ff2ae83fdb6b34ccca97dc0fcc392a5e1aee8f7fd26b1510841e65fa3a989c8f7aa206d9249f58c51ca9252ccb9443672ee0e43e39af64c7c73dd577a582be5a802eca0ed9d9a28371a316b26f7299c83fc9edcbdb3c508d1afd61d24029d7b9b84c96549f766fa50cdc4255ee57e9ece17d1f14d04d82f877202cbd7ff69843ae19f6e9c9cc441681d25b31a335fe1557e7fa84bbbc170d5c5d67b53b6105db750527ee627c0b6b192bba4aa9eba2b3b032a100b39d6483ec5fddc2227db94cd9623db3",
         "5e2d84443eadc5fd3bbfc08c3bd20cdcd3cf82d200a9def1e5f7d377b911a8733a914e5641ac46ce73802bd65d30a07aaba4b310dcba0c320fe397bf9f50edeba5610de56a41237d8bab67b13171c2f4e29bba3367d90a5a43d5eda15aed15721ebd425a4d29ea219f945720324040c9906c7daf97e8fcec5a623f34946052aff09da35b23a6112dd89e52169bf06f3b809b3301c47ca9ee1c83e9cba9e89fe7cb70a954d5b06dc8df8c49730ac33a2e32c9ddd638e384e4b0da3f170f0f0082fea324b8058edbcd99764e6065538d6ad544d1a568d0cd84a927e00bb63d50e8faafa1b551cac0a2fc63bb3d642af095db2c72a3a1c271a979c397b04000ab7a"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "38beeda09596a9c25e84b604deb1b1df5738580840d80c1ebd7e91c4c2a648f8", "38a88ae5aafb639eae3bcb0119ea583fe92752084e136625e662866596604c1ca843d9e516754fe11e8c21dc49ba9f3df1bc653a7508024a71293d4c676136f5e85037aa7bcd46a9e8c0e7d27ca953fe9b2bda876a9828055130dde5cefd1c8732dab7cdf82ca8cf9e570977d4882ae91704e3fdb2153b2db03d94ab2d835cf94ce02c42adc843a585b33d8fc19eff18021522f89491a5bea1f0ceeb5dd7ed50ffadbcadb23da47c309b132f8770170f8ce317d33c6c263f3edb1114553f5775ce59d2e64c306d73acc30ee205d580cae11afd127de5ce3c2d22615a353bf7f110dac8a80e8c880157ddbeac9aa041d846880fa4cc9dc699221e35d71cacfaf3", "720e78c8fe0ad1f9cd33f6aafae0233e56e19a75f96e2e86faaf5ca1314d8ce5", "3520cf5056cacf5459063ec16c917b1c2f77afd6401ddbb31e977701162ee9a7707f15173c733272a9e375b21c433829c21dbddbe9e97ef0849850a41d3de645b230b5161fb81df0bc024255fc03a2cbc3b250e7a66312a8724ac4167d44750fb911b6e9ca8bccbb41e3af99b34c02ac06d639af950eb363ed60bc21e25515e7c65585c47063c173d91ac4db834b5d278370881b5b49d1f99e91d77284bb4e04bbfe3fab2c6af8ea9432cd3b1f4df76f6293f5fe3f38142f82884846c7358482c0f86776fed29af861bf2a7498e802275c72dcafe832dffe7b26be567baabfbe87e603384ddfc2c5ce31af47b691dd97b082ec2d9e7deae4a2234c67467f7575", "b75e4fffa7b658244f19f7ad2a493fa30b2b299f3c6bcf27c8843962b020647a2d6809fad624b493bc011c8606eaa1f8da5ff93fea1df01a81366b7d28b70939ebf264971158a8553e986ae63b5440efc4d8793a077bdd2858c913222fee6cc73c27dedb47e278cc90b1a9e201b4fc387ef154227130394e972d0a0bd52906aa162646b82d6caa6eff8dd6ff1b7d3d62c2ca3a1fa5d08ab2366b8291830a2c3947883ddfa08a0d673d8c313d168643981d2e684f813677f342078052ae825d7b0f69882732cff9e406373953234d5a222c7e74c256d429835bed874a2a8f971a9b28faba6f6a1d343716505f086ff43e3ec29b54a502b1b07a808c379f380d3b"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "355a0057bf8b9a768a03826877c539a1708f9b168e6d27cf4130f933687d5ca2", "af93399311624f0183f64a52532d65bd00c6c3f0b54c3b08d0ca57e62d13fce954ebcd086359379c915d45b5e495010decb4552441a35e50bd95137005f11f45921cdf316b6d4cca4d4f24a60ed4cdc00f08b2b52839384044bdd5fa0a06aba2fdcdb61e275771d63f912ce2032eaa9012007240129f033a588e9699865f9e72a2cab3257e196ba22a0849ca99643fe49b7df64f735d0f98ce4d63231c62104a99112bde240526d0cc58e12d39b3ebc849ded8c985b30c6811d79cafa483951266c6080be463e519b99e2354dee12d317f62dbbd9aef3e2366f3dca9d9a54d7e66824fe2abb6790a0da375ce6e60883e058a69a979a352a192cfb2a5aeb6983c", "14bc8f5db8c7ef9749bf4f1ca361f9fb66c7c7039870f2fb9e72d3d1978a2f4d", "a3a0862e4401381fb39965352fbac358d361b72eb8b45d7b3bb22fd489d369883685409b4600538783fab9fb212aa0908a58915d6c1a7b04e90c19f686cbe00902e04f40ba28fbeed6f2838150760bdbd34e5b5d95c7bc48299a77d4bbc50c22afcdf8f4574352180d6bc18f15653e3304e28e91667037a41da9347db5c959236a4f8540da601f0ad4ee7426ca178efc10f2002824f2d30f5bc688a64c3b7ab47d10bd7482edd0045fed0093586b485bd196a882c97821afd96bf568618f5336a071d63f12928ec75c12ee229feed7baafd6a67aec623b6ec66176726a7a19516f9a27cd9a6131616e6286e4a0eebdbf92fded200ea4d0fe4854b94ca2a0dce4", "abb24d65a0de0735aa69756d66ab3f5b85f9f251023325644b6e796758a307ef86a8176c48b9cb06e60eb0e40a817fa6f95fc205cc10a3d43c4c3c1c9dd3825fb2ab86716548a6d37691752a04197a213c713fcbcaa1837033d0e6d8028353f019f2f1f023f5bd6c4b903a92f56950c61ea74beab6016a4168a669b5ab3210af2d54aeb97541189ad18fd35fabd618b52bb16dfb6cdf535cdcf0b7f7373586086a5472914f8924cfd6b018c24122b3c4881661f5e26cc1f268cdaf768536827f8f09a284928a75921152d530d0da9794579499852d5f38902caa91a0dd905e856c06bc39d93dc4339a7e1a2883f531b3b9a20016066c82e42635594d52ea3554"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103",
         "327f4989c4b76dd69815fc8b44093eb0584457be58df65c0d83844509940177c",
         "9af0cebe2e1855bd4f103c7ca378ec119fb607706966ed025d8a4b1dbed2256dfbf8309d6d3a669626e9eef2e88be81b76e648560659d3141fbedd4269c55937dcbee9b1d455e585ed1948f2302e640ea7132893608a0e528fe25248a4fa6919f27555a49de438c9a9f561b7ac502b787c9f1b54e9f9e4abe896a9212e327edb44cc1d6a86cd06ac54a0fca1ae70043c2c751669f66529b494fb63782044bbbb1ac0ed283c41ee5be0ba204c205f17e7845bcc2a3ed69108a261b0795244ce61cdcb4db5f51f93598bc410d22438f677cac96a031d6e9d7be2ae7c014b773e350270f85ec90acf5544d0d3e012ae0b96290f3cc279f281784759ca516b302782", "0042f9e139f10d1b15eba4a652cff945050852bf69c7945b9f7c618881f26db2", "1c714dc197415c6bcf6efcdd0aec72053c0a3b17264c39e763ce4a4f7a13da27247615a6602187cc3a8f6e354c1744c7c6448bbcac50b4626b01b0058c7b14b8c5ee277ddf333e9fcbae62bd85fe3ba480a74b518baee109554f29f8bcb55c4f0604331b2cdd7586228d845fc4cdb45daf382d52079abe69d6148e3485ef99e0bf79f697f0f5aa4122052ddb8b5adb536fd03a6ff64b096c277b859664c031e4c38d0e3a92771996e4489e83989a011b13f0df50306c871fb3e35a01ab2ebd3ee847a748a2ae86a4a69b2f931d94fb6b93f625b25309b7da1f20ccf80556dfa1364d209d705795984e874245f9af6aeaf96fd79b0dcbf51de1f09dba4ae63f71", "1897e7b2368d242ec351dd195891e0938cfa12bdc1e70ba41900cc274cc91d7ebd488e34ff2612826b2cba781eff6cb7406b7b0cc2910077b4bbe0a1baff8e7acf242d8c5187de10d6fa76f7cf8b8e9c784482ad469b6d4b4cff355903f1a414925dc1762d90b4d5b818689e97f8932ad10db30a735ea1fda6301a6c4877a2bad418bee0bbac44689c2842aba762f7642e15dbda899b6b40e947b4c33fdfba843e2bd4411b9a733fae5982eb5366939d62211095c802eb103ae079f1de7693af51d21dda55b1382d751fe9d1b87bdd1dbea40b5cd91f90c237128219737ea1e3de5bafb18821418d102158cd439bfdfded374e6e947b8c2c2ec44e6f98933a4d"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103",
         "77a3a94ce0481ccce9e781a4316afa0654c117cc63af46973b3d0d569e0ff70a",
         "33d6d331a0230f4250e2f7ff687db71bbfc99e0b18da14dc353e584fe09c8ab0bf042b79f8ffc2a66f3da71bac80b98fbe9465d1fe2ab6ac3885a5d0934996092f077c367ba39bd151dad21616d836c5c5c9a9ba876ce42669e5d0d81fea51037e01c7d62b206db91e2b081eb2de33d3078c20bd40bc5b8df2f9a393da636a2ef7ba818bd1aba840092a5ea93cd06cb087102ba317365bf397118561217d43fb74e5d317a52989857f3cea369e3bf14d967190cd3b9a266992e0b165f113aeabed4d1c3c88f5f68648ba93301fa0a9f86a034bce7df49349c7c2245e7fde1f748e4874910272f972187a796f74ea204207b5d22627a992ae7b83b9c208b8298c",
         "32954232cff445b8bf155f5c6f4fc6a5a7b4712fbea320078d065ef92391861a",
         "42ce4735c9887614a2b0806dee1e3a0f2e68c0b76ef552267e66f0c5c14fd7f6217e8c0dd360978fd483f9d5f9f6b228c95404ef75d6aaf0dd6074849cce25854722f5038ffb9f6e926dd38b0aecfe28c4e7a603d3ef127ad167686c1ad4811931906b7a909e33eb62cbf244fcf06ff74507e7b93aec4818f56443e2f902c08b966a29d94ce77f813185cc1a9dd74e62f5aecd887a1ee78a6dfcdcc6202d83479da3c8eef85127638ae93fe3339d4bd5440ce4d60b3d9b690751704f18ccba0d8b7f9129ff1230aaf03a811a19719730070c5ccbdc64c1be3582a629b3861778b6eafc3bf1cf6e75a56db549aaf65bd13ac4813ef352250b5dfe438f50a11d11", "bb6245d129e6bc23346cd8663279719ed8fc56c6ba108e565bda31116902d0ca91c45f7344e13730adb85ad91b2ef98d715856ac5f6ada46836f1474adaf0529f1277fe8dfbb40b7af20c4e3d2a0fc26ec5a75abe084f169bb59680f1def30f56e685805202af6d7b216de447be25c473e0e7714fee20258ce12babbda8fb6af8bdd211bfbbbf5885ae4aea07e633c7efc89d5a3db35ee314185194841b8918ff945cacffddcfc122749a44536a84b33ac0c908f147e2fef8b91b06349e8743ba816ba751b481bf4b7bd153eeefb761f920409cd26ed1d8d74b073f88ed7015b6c90975a8c1bb24c04893c4efc5e8803759902878f7f4d6b4cd5080a163c06e1"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "cfff85ec5427db152d9c585676a43c2ea3a2be952cecc20c960dd5fa884f049e",
         "86fac3b6b5f595471c5800bdd592a7f40cbafc04f9f358f341133d7761b00dd891f9459ca52ce82c88fca1d3cceb1419fcf0cb268615c6a02917914d6afe3af22408c2fa9a209e4648c39b6251728c8ceca441a75a63237ca125922a4e58e741686505072cf3f16843ec291329638a043c3823ee9c1bf5b1ff2055399d91f40bc0dbbd1fac40c4d85460b20aad6461308898ce27221dd8b8702cabef4116b77480e52afd0cf3ce17d5256314548fe07287f832d5c2adfb37da421870bc15c56a0c05183d6d9f9914708545729ddcb709144bf980a078235cf71a2ae20d3ca6c6a3d458f6b04886e3e8a5b7ff176336555a69123b77d77b95163ab1ddd58bfefd",
         "17ed62da1a5ba4e0a6abe4b9e10b36fa92c5b2e5893d1d50b9ac0711ac407a95",
         "7564a353d3c4d1b371702ddedc1917304fb5b3b99dad2ed2ced1096710c7810343245851435b9813319c5e02ce355627e449d5a9ecce993966677206b49b68031e36fe3a604e8bcc15570d2ab73dd26debe0893b9f63191e21d4fd54135b05436be389a8264c9118f44a41c3d6f557303a1cb40e1a5eb2c07db30ee5eb9458ccf4ee84e0aa0d3b1a33c589bc7be29d209e5ed1839fdbcc10b47baaf64a3f6063ee9ee4e06bd6366aca0c3b23e32e9b049c22cb32781baad4f39575e688c41284d830d1bf042cb18c8722b95a619bfe8be8b90fd1e0356d0496261af97096da20737ec7143ee52dea4c8dac7dce8a42ba327d1174304991acbec1338d8f400f15",
         "b250aab88a989862203284c4ef597ab9d136d5fbf0fa2aaab73af809e0820dbe8c0298a35e7885166342564dd041e51a9223d2a2469cbeba63948579ec97d8646d7edd6b4b962b265eb450ef0bac1c87322aca3224ac8887c06c695203e04741819905fed639360a2d274aae9eca71072c4dcbbc45117b5d9bf49275956d80ec6e4b0687bd86d3d3a63688fea545113d60921e1e0f77722b203a0ba3019c2c2027bac96c5624bf56e52305c305e7e48c399ab5b6ff60de7de847185d39e545b01a58dfbe5dff978539069dcb8333ba4d251c23993f60b78a9cfebb1f8e7a5475bd0e8cda96b57145234d6a3b7fe70886f7a574f314935c66ba6043d5ff530648"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103",
         "4924a16552360ddc70c6af5f234540257ac2b70c93f5df5ab0874c7134d46603", "6d1a8a34a75d83829087a15a0264ad0301623309e1456947f7946218f98e69b3f42c03863d04606eb3e70ccf978c1d4b2a8cbc5d75b0a25e348a6e5d07f4f27a44018b9adf6a1da191f01dcc09cf895869c602243f52e46ee9488f058ec79388b9056ed3c65ad80440b19a0f01c16a9c831bd9b8901479c5ab0bed11450c257fc1c515b9a017836ebd900c082883ff7057b9b09e13b91e667954c9ce13cb87c990b6cf0f9c7310ccbd772557905673def545fb2b93983090bf54cd30ccf8cf2b9aae2c01e864d2f15d67f4f5af9c07449a8f27607b3061104fa34617a9d1eab5a62fd16c447324d416f258b2c6734a8b258082306c8e5e5cc0e01741dcdcabe1", "07434fe3f4a6015ef7b666dbe87c68ff7b9f1acf9402926238f4d5ae21a59ec4", "ba9e7f17d8f28e34b82fd8921ed9a890d30e24dd7d5871d6829d2bcbe8c2806e0b592763dc062104d392c74dc23dda0e68c80c40b00d249ab420ada3a495c518760da3703c39bf82213cae2d4d0a61b20146571fc1e4a7c51c0a37da9360278b8c6867a5f9395a5b918d3fa178f8839b950b753a3d17cdab887fcf8d4ab825bf8ff1bb25a301fd50d1a3e188c2c1b6be74f3a284aad7d162485d340289f5930634c718ae187ae574c2926a1749710e53b4bfbc138b4140dbb7ca9544ff82b49be96ac311996de39a96911baf829b626f8572c9ad74a2a33d4737895b58fc5b80c5b661c779a7415ec5ebb90ed7c0e73f9260ce36c523b74b26b8d44c33be3367", "04b8a753472150e20f648abdba73824926b1458bf9f0f92f8e217e0abab83671855a81914d59f4cbcc41ccc2d27b31635fc1396e0635d77567abc3cf853abb0e52749969d92bf546a0574c4ae98633cda216b3598886a8e97d7254891f8e74bf9347616af61fccbb321857a3676a06f4f0201ad3c6fdc2062672d6ebd20aa26a599ccdffca98f2004c2dda2feec9ca41b987742096dbe8dcb66c99a2eb75ef29e28680297085f5039e52b50c737bae322984498fddfdba4bdf6a7c42a2ad29bcd8e817c775c2c8549faca925325ca5221ca4060269bb9a868fb25d869d0efec381c2bd2e464aff1388b459362742cb00852c9068551bf4195706d315418552dd"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "6b67e1f6f9eb47e1496699f791edd7c4959702f3d3538b8bba95ea0a8beb046e", "5140d66d4deaf8a20c5ed32db2fddfe3f879aa997be576953462276f34d70704fe7c544aa659b4fdf76458f2cf5dd7380392c9712107a145d44b09b56d5dd42881f6913d30fdfdb63c456aed7ad61a0ad0908077fe66a1ce381c291bfd1b603a8b282d70d411f60678f698ab592a8e2c77a70e2ab12cbfd939162db2156d3cda6095865888ffac7ac2732bd43a66f51291ebaa52cd5e5e271e72aeb6164c0d73d13a956cfb964d7fe0852a638fb743cd215ccfb0c84a7c951dab414b7bc219c03cbc33fa9d7cc88ebc8df62ab6de36536664802f4d949f84408e549883cb4d8394ee1149d82e3e98b312e811cbba09ff091dfd38e3bc60acb3e6caa7a32573a3",
         "2e24154815a70317dc6a6f03c52cb936e102588106f6be9bad3747df3aa175a2",
         "66d989dee3a9fef32595ff1ea330cb97dd91c57a9d2590b082bbc2c2404875f99260a937e4bfe9d4538b951fee1aa99691760f95da8e3b9e5514a0bc1146255ac72aa19666d2acfa1ebc2708d0c43d081d99c1db8faba959a308452742069720fc1ddea4e8671ac76396229d65e46109169097ab0d9d98f4267db14c26227b2da491542cccb778dd3997edaed044b8ebf12123ca86419b3a52a62047ee2ceca6c87b34e4d74178c3773e65cb084f25f809a1ac641eff8f3319b12a06bdde619c2e5774de7942d714ac69ce677b43ff3543eb303f593103bc706acf6a053714da8417323863d45e92663557fa7bb0dbdf25568de60aeb90d9f0ac59998a783ae5",
         "7b0e659aa0db1a7791ce8dd5321d19315ca27e878e12d3abfec8fde85ba880ef65d6d914137150ba0152a7d990831e60227622d0c10884d5520bfa51fd881040d073d80c1786cd57f9583879d93697b14f61e37307ad1df5249bacca9ec29192873b8d719ee6de199b0f7c235d5883aec38e37e5f36aec8481de11d386e3450e8fee8551c62682b12aa86c3d016beb5982b9140d6bce8f054cb79a214f9acabf1238e90d88fce74b9a1d7ade6238c2795f2f01671896b365b35596d0cda2225a4090151d0e7648a70edaa2269a8d9aa8eb7576e70b0ce809bdb0aeca9cb123fbf9834078969867a9944e4424e40f2cd25d47c0456d3b91daac5fd4493138d58c"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "d49502edc00aab4e2efe0171af0cbb9b9d80a53c1f5671819388af243187c496",
         "af03717cb786a241b052a0b8adcc113c6d735178fa9414f1f2d0eac35c925328116194192007fbf5719fd35ce83bdac537542a77ad4b4ea6a3b5c8539fe1ff0d06c70a1e51caa4128a3161518a78d2f47ca5dc538bc8605fd41b7d2d9c4591728fc8dd776e7f5c43cea479430bdf9f0bd3909b576ca40b0b8af4bc2c35dbf3e370573899d605b8a9ec456f3d7aaf616c91d3474ee9d2d2b00f7605c544213d8df26d971ab30573b00a92e96ac8320786fb0a2c3287aa6c0c2367170d39680ba0434e7cd77f554fcf5031372db5dd9b0ba27f07fa31daac1f4381077ca98428df7c9d6ce2e4392ffa9966b38d353bdeb7e8ac8d2436513531b4b0a26f8aa6dce7",
         "db0539cfbd20de2f665c1a4e9b5b5cbff18cccd4be1134f2d22f8f0ded58f6da",
         "358fde6ac7347332b77a4411c779113e326036bee71c11094264d6fe9df18e0a13f8da103057d3b380c5ece837a9097b1ed406ffc4a625916a688617e118d09f959c1487d128c471a32c015891ec7d6a63522b0cbea3b54541d0519be20de45f9f7be167e6e9d2b72a731608491dd864712b4070bb857af5574d34d83a9c5e16d7bbaa02e67068379575d70887a6d4e686c87a0a007e5a43d853279b9597a60b1c8f13cc4f5d7369fae0e458230c3586ef7025c4eb940e6260e666c6fa42c572fb00d70aa8cf4067e4c54e269ff458631e8cf97b0d21858661022d63626beb86dba0938ef834de48584a32dfdac040c893972cba640a51333790518133fdac49",
         "8b1e315438cc4085a926a3f2ce90267d03c4f326d9eb2faa13e80bf43127efde6003597e336d6fbe54bd726bd9589e6c1431cd754874bb7a0ad141324865be289bbe32919352256c74d166b9a4802155c4cf3d6cba95be42f20a1d0e54397ebdab5b794af463c138b6a0a25a90cf948fbe1a2d654b55430fb674cf31f010671ac32cea2e48c1b924dee3c66027526f2d37e84a5289ebdcebce7b00594c78d699fc8d5b36ffabf3a7643f0d292b399d9ca81bd5e262daf51af4a88e8ef1adc136dcf8a137fb48927edcb543449fd76ca5b7d8b5b41ad8dc448960f846d0862b32036a8c6da3ad9fd58ca6e1c44c47299d2184bc2cb682e2e25cc970180cd8c12e"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "17f82c6d08944392cb358a5b1d7f21c83e755487a013c260af84626f2ebeec1e", "65dc5939737aaf8eece9f804f10169f18e183423cd568e9ef6e82c5ef8fd522e20e37c5c6698e7159a86b07294d979b252a7c928f76f754fde3b053368a40520680af8926be670c0f4248a0d5a5a1dbaa967815421753ffdcb4374b60e2d0b4595bd728f84fa4385b1976b03f81ece6be8ffd030946982badd1bc38b14dbe8a1d2e82907aaf2910e76203368b137edd2a655c325d9ab564535b8221b2265df04c13e6b4b966924528d15e575990e28aa890bc31b24239084f3fb19ad5884afb5cceff8da497fe3a997e31f4784b99d2161da1b7a32ac69e248d6f2b40614065821f08c25d89186f58cecf54a975bc444494d0405dfa8207b52882c87e5bcc4ad", "ad173df90f1fd90997c6bd00f0ec52fbcae8fff84bb353197864f0c5c0022218", "a140b7f160196c614a51bb56d2a972fc26878c3cf59166f1f53b8fb5d9aa3b7262503b2bee4e147bf636d64ff3cf41d35927f6be69b16bbbd1469c877e221eb6fc2ade3e50e6b9fbf660a153b9a105e2f92f231d08be0150a043573527efce5c152643f86914a09e4b9142f27e39c8fbb6c8ccde8d955b7b612c92bac96da15b14810809fb0a07c23642b8739b4a092f4153cbe7823eb51838c945e6db50cf99a53cfdf6dd531f22cae48b014cbfc294c0643ee6a2219ced591fd874b87db5487ea70f5dd546a385817d81e04a84f8cc499a5ca79f58fa50ef3d2c1d5111967e7003a5e99e418ef826571aeec969d022995c87e7cdd4718aba098faf7a834ee2", "05c047f26ee410ffac75b493f126cd1737270aabf3b755142eb9a718bda8a12c51fbf144e9c2144013148dcedde05811b04c01698999dba67357c0d5be2ba1fdd61ca1c17744418ea93d186bffcee1a34ef65f65eca50ee9241b3c2b54eb37ff8453aad227dde4fb2a8524522384626d20f574913dd8ad1a5688572624f520a789f1a29e4b3aa7ba4b7d10d4386771e4af4984af8d53129418350b8a4cbaeeaa98f723c3afe275fc2a4ecd29c41803d553cd6178f7a2107286e29077d51ba66bd88ac3a4c2653c0367ffe98c61f1b042f304ce00dbfd392aff5409d77a6a0483edf22ae348fbe1702a00a526139cfe19ecb06cc8cef3bf53d630893cec1ad5bf"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "081cd4d283c479be3660e139c2d92b24e7bbfc634b73ce5e16504700d5e58d22", "b35b9585dae0cf8f2597f8ac17340cc9a041925cfa200174a4f463c6ed9a0a748b2109f2308becf722880a89ef14157a95a8234ade4d36c04c20267ca1fef4cbbfd347eeeb7099ce547e376850e31e797a2c094a5278dfb87f427c94a38cbd87fbfebd5526d9cf2033ef258b7868c43968cc58e2f089a658516fb09f5ee0474c60e5b60f67a58e90bb05be55e59a513a7e0ce9495e12f5f49dacef852b772df3f90a5b0595d345edc469cbeb5b69209e85d8cb86d540c911e6046830c31186b8b2d1908eac1588bb7ac55976c5dfea360840e5caf7c3f27e69ac023c68107453b64d82a38801d34d60176a250e38f4497c88138d2c251a04ab142a32f31b7344", "11270f8721afd39a14ce80dabd2fdfcd4fdc7dc994c1855b6b1f59d019fda337", "1a11d470095faf7e3df62806c6adf88688f737ee77f05472ea0b1df6f0650e0b4f7d807672a58c8cd4615b986e45605ebf37c28b703fe6e9487991a439bc89122694b6d9559d67c144d54f6aa46b8ceebeed2a2962a153ccb2d0e2d726e7a760652c5a297b40a1cc0f960c2d327e74cff9811af4dcd7d398a92be870a48e22a76e7c08ac30e00d0bbdf415c6646d6b042c33025c797f1f04f9a81be7c8e973b6ba66170ee846a05c393fab1e1814ddf5bbde7ab840002c02636bd608066b050061d605666ef2ba3711d2f3a54de8a5a275007eb3f0bf6d74ad21d2d3a3717f7510d2cd788530f6ddfa7aafc12f3a671a4890328713afa87907a7630c5c342edb", "69a3ea81fbd9cbd733fa6e0cf8873bee3d22a27429ce41872326bd50cd7e13e3d01a9ae53e1dc310351adb719f6142cfa0eee7a01ba2723edd70ae54be4b7be4d222ecf03b89722d9312a62714893646b0b21ea85d9bde2b29d519ff8c03f56d860805f4822c81e6681b9ed064fe73b767420649554e801ffa62288feece8790be4fda04861d861f7cd5a3c29403deff7c51676f8262fa1b4020eeeea62d3f70c5f49f6092db06b8d835cf5f44d7e4ef87268916418fbdfeb7944e2b2564653799e2714333b532bbbed68a009f616d4ca03d83c84562596ab66771a7059256daaa6a42e4dd9365ba374cc80d7d9b364a9aee8d37cc2f90c0b8ab575d972c11e8"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "c1c77ae45b2175615ca7a8375716afd9b867e73a908f1f7bc9c3c8c010f2ee28",
         "58c79abbc5aa8e755bc44bc93e317ddf3fd1761c5ebcff4c741d4d9158cb5d939ba4a18faa8010a99f773b9b9c59744b078e4a54a910439e9e7e184edc2442a7ae4213f39d2e7223d40cbab60d9f1636629f071df67b4695ac9522105f0f2f07ba6c13539eb36ed9f58d62098502af4f8b8e48bb6781c4ed288b837bd58923ad6e4d5a3603652e5bbea70e48c872d529a34b52aec8b6f8eff0582667835468543654554d58357423579e52268aba8c528a4bdad04ab7c1affcee41a0d5938c176dc293c40a092579445777960a589606b19a59dccf9fd8f6f1976dd5e84c70c72adeffac47f229d6c3eeb9be3d65266d098f95b73dbc0d9cb6bd75ed636fbc2c",
         "0b5e36f6a9b8b943c2c479c2f9858a03bd1ff8605524365d2d6dea6e60eef289",
         "93dc1e6eb3bb1f9c800f08a59c1206c3124f216fc1bfef38f9d0d6ed7fc8be32e7fcd691e06e16d74993525c51ba798c457f9efbd511fb6af85cafd7a91462586732e09bbd83a446a4cabcc5486b365080d2e823bc2be7d29c4580c70495634e954f53d11aa964ab5a5378053e832f48e792b807d0997646ccca42d2a0a0f0532ea12b3972979dadfb29d9a2f5ab393fec2445890dff19d3458c8ac5eeb67bb993594982405fe7472528c7d98ae9ba2e5ed9b977eb5f53b8e7346ba92a54631a83a3310334a47363ea433d8b3bcb9f75d25d29b3a12c728737aefa980e11cddcd8f7c92f4c1c82da1ad36ef498a0cbb21585ba28657de723a4e0c3b359a5df63",
         "35b8ca4ca33871a0a6a9fd86b391dbff281763f8e12d8838572d01c2b7f1f229250a76c765b172b5a22884f03e8018debcf9903ec8c46889bb896a4f1408ecc7b7f54bae15c72fdebd124a65d218f40b33edd1449164e8165d59ad03ae7718c4dbe431159d39203fa5907d922c8f2262631680c651e168e5693468e93eb5d66cfde24c45b3826e5e35446c61333e6fe5510069239a246fcc04df303a0caa9a009644a2e9ce98504c77b5418bbb94eedc909e923e4fc21be9d4ad66d27b5fde9004ec273c8b84781459ab01964c1b066220b15948d238d072eea0fa08d5809c909accdb9fdf248a10d0abb8445c28af2d1f88bc72562fbce2ef9d09eb2e2d8872"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103",
         "2e8f5b66488755966a5ecf8d23a3bdc7f34b15548712d54ab1abddb029c9e580", "52cd362323e817d06d3fe87574bdbb290583cc952d3be93bca19914fe0e4e3bc8d735a332cabf1e66af16d41e01b0184ef55c6953e66125dea1b0db2c873a50e96828be9e38d03f8657ad4a0a44b484ed6fd17e4bc8b1808a2cb4ef52ec2e95143ec2c0565f4dfa3151231aea3bf10d1e7ff07eeab4fc9cccd87ad7c038e5366c7242d9f2b72ce3183f1e8707b286471c4dc610c721cd9c1425472cb6e9e085fb8334cd0ed4a085306756466be07c58b9f0582d803d32aaca0b3ca82ab334518afbbda648b3e239c4a8e70464c6aacbc36b87c4654e5e0d8a947c59c91f121cd1854a848448612be73357f8df2223135b21f38676dc30b4c6af92f497887712f", "d7792a79560a8fc7f60de3390772a0dfc2c9d1795ecdafe484613f5684099b55", "9988199cd0c74fe62fc69d0a73c4239e84abf9b61c81599b7766625725f65bf87685f8c5d4f0b3365e83c8430cb951d1033f6a6ce3aaff8cbc910d81a951f307e8dff4b1f60c30d4357fe5a34b4f9ddb9c79e3663e01de45e408ebcb8b0c64392a4cfe05613aceb97c2565c66c3640e9658501937be4cb16f7683127e98882022afbe93c7622d780a35a1084c64ea80a08f0b02cde5080ef0f51e164903e9cc6f142f59132ba510fbfeb46fe3f187eed212749ba87edccd639e124fd17013d255889dc7654ac8be831d0240ae63f1d6aea2b78669f3a1bca19e3e05901d4a9782182a99c017bf7e9934b56f7f597fb3ec37db4a5687b61bf568c24275a2ba324", "04c3d19eb7919254d640747eb9d24ec033598bc271b8add4b48d71e8ab4ef82fc68b4b19a8645a88d21a9ef0b8c4542dc0fb555490f622fa51ddb6ce4ff84a17ffd87cfb38a259155d6c265d70ca6d04c12680598e218c865b2990c6c5730c17bb93bc620b79cd1ebe94cf15c7358c4a0ea73ef6e3271d31638335251ba1092d01962cb851d24d494f4fbb82c9b7ee036e5c6427d6d205d8d146db9f61757f537f043e419f0250e2c1b74041e21ca854c6489513f3a2b58e3ff70d19c96a7f26ac9c29a5f16faed83d1fb7850b41792e5646bce6a21aa586d068f642087c54f3317941e617790bb03f3ee31c6a52922ecb6ba80493c3d8efd4f8bb3b7cd4810c"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "8247776d9562de20d47bdb53a90aae76ad99d7830a0fae27bbeeb42fcab63be8", "a0f1ba2640663ffb1a6358541db85e0df7fca7c0aaac32ffefc819d743d9aae8791c060a5ba3e74b661485dbfc96824ccc2baf3805967d2ffa25269446c6aff6615aea564c41a9694780c965880c0b97ff55d05254a8ba58014e365dc72a42a9cd9d6468d0a33e50465bbce445fd98b7f0436c4f66a227b82c380173717c3164d95a994b7fe5130928db7e9e26ed69e2c294b1a91599e7ad36711318fab7cec8da86bfabba99d14e01b034e4caed3e782ac542ef54ac210c340f2f25c24ad984afe552bae80a114dbfe8ec70e043219104678ac58406c13a874bdbedfbc09fbe1a0828f2bd6166b0dbb8617b636be4f68fb9e5f2561b5a10f9dc139dde862dd6",
         "c1c327cbe6f534b60b0631ec2f0c147b57d379d7dd25078fbe5ed110f315d61d",
         "7b3c8d89aeb65359575883bc7e0357d8e836580274f84aae2875e20d988a2c71c3157dbc2f69b75db1a9cfcabd44770105bc83d269159d3b9f37f38f6e23dfdc7443f4513218418b7408a26eb7d78fff014df4ce53d48e2d6394451dd690c6c88d3c2b4a83359f866510af2a82c57ef1ad9adc1e93d24dcec5e7be7a97071d3f9dde174cb3ec683c6d2a5e43c1895866dbc58f4a8bedafdf076ad7e2043b56e8fc2bff935638b223fbbf23f85ba927f43be2a3a850b97b7a2b745e03e187e37dd7e09d7ce646902994277164cd20b77bcf08a47800cf178fc1159c7d176392cc69d1aca2afbeeef91acf7511e374d40e983ed3727543b56ac42044fac728430d",
         "0a81c3e0977bade7395a9006211ca6ecdcf2e2190f08096c9f24aec8c5c378642fc1d635a7c531c8c11d4bb38b890aacf5de2805446e561035c4eb270c7564ed7cb4c9b5f1eb134b08ea2bb061801030e6ff83bf10a213705e23793e79f06aab5acb03c0d45d80ce47dd2195d607fa8c484f93fd7ce72cfda197535b9defac47fb3b857ea5e5c25a73c7a6f00bae383aa6c4fb4e308c02ad89787f3e035e67f9493bfe8c0b7c2fb4d81fd58de90fa529bb5d37ad6081a97b8fc476022842d4ddc9eb9b27bbc192ee533f2d6123e81b809e40cd1d9e59d77c4a2021aae56b79663cf06ff8ad04f3fa194f238be7357efe4c2525fa105b9f956a3adb577137f932"},
        {"c170a05419ed997cfe34143808f447a982c91cfa8238ba3fc12d1bfb717843aa99a4a27e1d1a9797440be156391be3bb2636c2bbbdf60aa3b80bf9df700fe58322b6c6c18e813b213d64709b4178a54ebc8feb39766c1b7d93fd55db01b8e284ba68f528f0b004aa436a9e3b7fb30f4b86d050aba98cdb17556eeb4e6c2c963b00da63d739185d0cc4ac52232d288945dd1c50e02930c3b186869325e987defa04d6e5363a2f5b5e7e1b9246199f493fbb4cd018c06777f5138a21c0fa8b111248520977b472ca4c95456979bce3dcf483102a58b1dc21f78a5f23a13c72458aeebd0b685497c91a66b70d3ad2f2f009c22cf60f23e5a47985cd4f5731094515", "0b3eb89f51aee5f9008b0712d0b8312985f864f1e2cd112fd945ed82928a688dbaf83a23e73ea84dff0ad532b8d9e04df8103ed771a6342f0ecb5e4364cacca3d1a1aa41f12444f1fbd4c6a0d7620fdcd378affeb9802db0730c3ac82ec99641d733450360cb84c7150b07ba7b6a3247eeb63b5d35b16ebc026f32bfd8bdef1e3cc2c41abecf36f39909d9e3d1fe7e6eac0b94b925249b7a4c1cdab82e5937d993c960d8fd88860b999691bea622fd2850c72d1c10b35a32c7a7b662523750da17b6d6992606f179467c36aa6b2a1777843c3e72e066c77ccce82f3791e7ecf85ca3d5a41a5695e7e7ae333ab1d6f6cbd23d2ee0956346c31f67b4a0c9ae04c5", "cb948c28ed58de1b8ced8cf451aa0f1d8c6e1ca14caaa09bd31ae1467f9683e3", "ba55f824ff37b9e2ca94d2f5b5756c592a74aed1895e2a64b8ee47cd6b6e8c05",
         "b7896bad94401daf346901f6b3b48d6d82bb86fac1f7038dc795d7d131494b2d6957fc4a85476a9ea28659c00371e8b81f83a9d55506488dc7f964f5a7cf747906262e8940b9359c623af445a9d82478b6a9946c6e28d55e2f29827179715b8ce0269eb21dce3a112ed3e38091559adb7f4cc5bc8cc719c3cad6adbba9a0201932a3589476d69171ae6c18354a6cc5f7ed8aa60d5239b20fa852c65ae57801c0867be164ca7c199a88fe5fcb33b81601761340d7e124a7a3b70b7fd371e933750a43bb741d631e4dde965a373895e0be090838585f3698beab147675519d9b36cab1265d8ea550a1a9ef018bfb2d222ed4da99880ab54e321f98e65bbea72575",
         "65fae866df2f463bd596159fe88efdfc9bf76bb47ded413a176902bb8fe1b9ff",
         "0aef33da26c75f03261b2ce928765ac3a546eef8d07242fd8a7e3bad8760a5349c90db18880e9165fbd11631c6b07f88cdad2be71f21dbb95be744ad7b62d4a4a226d16429877dc60ecba4067a398a2d434ab9e63195987ba1d73a9b9d0dbd0fbd6c938084657bc35b3b5c2d4037789969344c58f452654057421486355c806bc8f6d2c3ee6b0694b012241f2d739a349043d46342e72e2da8ad15e92005986ecfc90b93c2c1100081dc2eedcf8f9180d53c1d7a81e3a4dfe71f233a04db0f10680c0fa2d087c647b9758f2f1e347388524b8865479da7aa2f736ee8f828fa157f405d6abb762f62a6d83deaf7092ba06996018455234d1673b86a63320ff9ba",
         "00ca89b9c87e4233aabda6cf39cb3ad74c02ba29fc7a35ee6d7a3ee05261704d1834c24f42a695d470494f66e373f87dfeaa414478150ea54560db0dee5f4a47011a6a2e522c23a33aeeb567f881ea05522de1b1173d3713e6ebd7e63d8939afedc728021e2ea613d4899e3187391d4c838f3ac979fa11cb704b71f9d586cf1134e039546cd243c935f19ef04614f7d58c808bbe33aa71578019cc5b665aa4c7e6d23249fc7202046c059386c0e85076dd4f2371c6ce16df7804d8002561c69fab27160316f45cfa9b3b3645014ed22ea38eb8720dfcc2616cf32cd6454c911c64a4cbf3b38f6608d2604a7e6549184391c52348c14b2e5f282cecea583dc65d"},
};

static void SDV_KAE_DH_FUNC_TC001(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();
    Hex *prv1 = NewHex();
    Hex *pub1 = NewHex();
    Hex *prv2 = NewHex();
    Hex *pub2 = NewHex();
    Hex *share = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);
    assert_int_equal(ConvertHex(test->prv1, prv1), 0);
    assert_int_equal(ConvertHex(test->pub1, pub1), 0);
    assert_int_equal(ConvertHex(test->prv2, prv2), 0);
    assert_int_equal(ConvertHex(test->pub2, pub2), 0);
    assert_int_equal(ConvertHex(test->share, share), 0);

    assert_int_equal(RandInit(), CRYPT_SUCCESS);

    uint8_t shareLocal[1030];
    uint32_t shareLen = sizeof(shareLocal);

    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPrv prv = {0};
    CRYPT_EAL_PkeyPub pub = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);
    Set_DH_Prv(&prv, prv1->x, prv1->len);
    Set_DH_Pub(&pub, pub2->x, pub2->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey1, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_SUCCESS);
    assert_int_equal(shareLen, share->len);
    assert_memory_equal(shareLocal, share->x, shareLen);

    Set_DH_Prv(&prv, prv2->x, prv2->len);
    Set_DH_Pub(&pub, pub1->x, pub1->len);

    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_SUCCESS);
    assert_int_equal(shareLen, share->len);
    assert_memory_equal(shareLocal, share->x, shareLen);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);
    FreeHex(prv1);
    FreeHex(pub1);
    FreeHex(prv2);
    FreeHex(pub2);
    FreeHex(share);

    CRYPT_EAL_RandDeinit();
    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_FUNC_TC002_VEC[] = {
    {
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    },
    {
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "",
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    },
    {
        "bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
        "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
        "",
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    },
};

static void SDV_KAE_DH_FUNC_TC002(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    assert_int_equal(RandInit(), CRYPT_SUCCESS);

    uint8_t share1[1030];
    uint8_t share2[1030];
    uint32_t share1Len = sizeof(share1);
    uint32_t share2Len = sizeof(share2);

    CRYPT_EAL_PkeyPara para = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey1, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey2, &para), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyGen(pkey1), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGen(pkey2), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share1, &share1Len), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey2, pkey1, share2, &share2Len), CRYPT_SUCCESS);
    assert_int_equal(share1Len, share2Len);
    assert_memory_equal(share1, share2, share1Len);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_RandDeinit();
    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static int SDV_KAE_DH_FUNC_TC003_VEC[] = {
    CRYPT_DH_RFC2409_768,  CRYPT_DH_RFC2409_1024, CRYPT_DH_RFC3526_1536, CRYPT_DH_RFC3526_2048, CRYPT_DH_RFC3526_3072,
    CRYPT_DH_RFC3526_4096, CRYPT_DH_RFC7919_2048, CRYPT_DH_RFC7919_3072, CRYPT_DH_RFC7919_4096,
};

static void SDV_KAE_DH_FUNC_TC003(void **state)
{
    int32_t id = *(int32_t *)*state;

    uint8_t share1[1030];
    uint8_t share2[1030];
    uint32_t share1Len = sizeof(share1);
    uint32_t share2Len = sizeof(share2);

    assert_int_equal(RandInit(), CRYPT_SUCCESS);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    assert_int_equal(CRYPT_EAL_PkeySetParaById(pkey1, id), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetParaById(pkey2, id), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyGen(pkey1), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGen(pkey2), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share1, &share1Len), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey2, pkey1, share2, &share2Len), CRYPT_SUCCESS);
    assert_int_equal(share1Len, share2Len);
    assert_memory_equal(share1, share2, share1Len);

    CRYPT_EAL_RandDeinit();
    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_FUNC_TC004_VEC[] = {
    {
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    },
    {
        "bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
        "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
        "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103",
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    },
    {
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "",
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    },
    {
        "bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
        "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
        "",
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    },
};

static void SDV_KAE_DH_FUNC_TC004(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    assert_int_equal(RandInit(), CRYPT_SUCCESS);

    uint8_t share1[1030];
    uint8_t share2[1030];
    uint32_t share1Len = sizeof(share1);
    uint32_t share2Len = sizeof(share2);

    CRYPT_EAL_PkeyPara para = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey1, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey2, &para), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyGen(pkey1), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGen(pkey2), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGen(pkey1), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGen(pkey2), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share1, &share1Len), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey2, pkey1, share2, &share2Len), CRYPT_SUCCESS);
    assert_int_equal(share1Len, share2Len);
    assert_memory_equal(share1, share2, share1Len);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_RandDeinit();
    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_FUNC_TC005_VEC[] = {
    {
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
        "3abef2371deeb26adfd40c1788b514c5f420eb09fa5e1bc0f9a552b1",
        "6088cd6a9308c4418d17f3c2764c5ac98d62c5655a3128b6bd2d81a6f2937347ad8d8dc6d01ca6a231bee08c187261ca963470e0cce76c14cf05e9b7b391642ae9d5c5cfe99d49d352d5f8e772815355800550c76c1072098216183e580f973c1aca1244a3a0cdd322ef6a70bb3d9d6067b8405191c7c217e11e47eee85adee1ef73b4aa565233eb323da013b9fa00b0664de3aa289ff70fc6339ef2b94ecd2bdba9017e9503b149559348d1cf461f41e8a12937157b71b14b7e514f907d07e95496874b559ce25eb6c6318b4ba050ffaa521b8b8233ce5c93cf0c2aafd4a59b27268f943feabc81e15daee6ac847036cc962d28b4d1d40f3968c695432881bd",
        NULL,
        NULL,
        NULL,
    },
};

static void SDV_KAE_DH_FUNC_TC005(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();
    Hex *prv1 = NewHex();
    Hex *pub1 = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);
    assert_int_equal(ConvertHex(test->prv1, prv1), 0);
    assert_int_equal(ConvertHex(test->pub1, pub1), 0);

    assert_int_equal(RandInit(), CRYPT_SUCCESS);

    uint8_t shareLocal[1030];
    uint32_t shareLen = sizeof(shareLocal);

    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPrv prv = {0};
    CRYPT_EAL_PkeyPub pub = {0};

    uint8_t *tmpPub = (uint8_t *)malloc(sizeof(uint8_t) * p->len);
    assert_non_null(tmpPub);
    assert_int_equal(memcpy_s(tmpPub, p->len, p->x, p->len), 0);
    int last = p->len - 1;
    tmpPub[last] -= 1; // pubKey = p - 1

    Set_DH_Prv(&prv, prv1->x, prv1->len);
    Set_DH_Pub(&pub, tmpPub, p->len);
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey1, &para), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_DH_KEYINFO_ERROR);

    assert_int_equal(memcpy_s(tmpPub, p->len, pub1->x, pub1->len), 0);
    last = pub1->len - 1;
    tmpPub[last] += 1; // pubKey ^ q mod p != 1
    pub.key.dhPub.len = pub1->len;
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_DH_KEYINFO_ERROR);

    assert_int_equal(memset_s(tmpPub, p->len, 0, p->len), 0); // pubKey = 0;
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_DH_KEYINFO_ERROR);

    tmpPub[last] = 1; // pubKey = 1
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_DH_KEYINFO_ERROR);

    if (tmpPub != NULL) {
        free(tmpPub);
    }

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);
    FreeHex(prv1);
    FreeHex(pub1);

    CRYPT_EAL_RandDeinit();
    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_FUNC_TC006_VEC[] =
    {
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "afc02bed59a56d3afcfa34251ae7d169433407a4be5d43ff3dc3f2e6",
         "017b4fc17763edde285de27fb72f932f330405ab9e6b0cdf9c2876386c15c2a3df2e1efea8df9b5f8da11f518be5d4674500eb770f6ff8f462264391ba75c737515b6c3da1e4bfe8cfaaba7990359e3d8664fcb2335a701a4071a84e1c867120860d7f5b40a3804c479975f91439c378fc78dc0fa1cddda6f124594324a2135a94fc61098d2cc24eaef811f0f25b22545a0dda117731308203e6d1620fddc6547883bdf3bab578b0b1acbf948ce3cfe48502ab864a9a6aae89e7bec0d1be1e38173bdd9346ff0c5e84c9a6cd7fc67e469dbd82fb8483b1054d68e1637b8e73c654f377730a50ca878d928c5c0011c215648bd2e3ada1b6ac9f98ac25769c7eed", "862e856f6ff58fdabc3007fd0149e9c3d22346e5a4a97471c06f5bc3", "908e1cac89472f0823092ea7f91b240394cbb1de63d79a3b5a1d2f0c4597bc6cfc4ed1884130efb58364a8b474a9061ed425ac27f1e13a4ed549334e4d8ab675f532f612a1d8e4b5b2fde8833c6bf607e7fc44744bf042d22bf48e84d07eb1bf569f8e6bea08298f1b8769d90558dbd855317ddc6a1b5355ca2304010399ff5f9406a7365ec3539063e92c92e16db4b098e36e100b608dcefb7235d60f898a0b2cb7173321ea3cd390f1a8cbc5b39668041b9f3d9d7abec2d3e6a5708c23a42177b597fd27fedf0ec83482762a20576962b8f4c34ac92e35138b991b813d2dd2fe80d3356a351c616e13ed3b7680ad8f314321cda7c57d69e2268ea1f19dbf8c",
         "b4857900d94d17d5567a5cf189f6456c911490d80a2eb8a7a1f5a3f633e8651d84949ec1966a56fd7e21afc3c87acc2ce42b88f1adf315d381ba4d40379d5c25170fb8141433d1832f079d1acebdfeb0878010ea767b9b822e99b5293e7d0516fea6170b3ec6e6b438158d7873793089126df98534e31f5993f54185304effdba4ec16470b488e17d00704cca8399612da1a0bf907cedc7502bef04563f2c7c540c50034918741d4483ad1699088f86cb161c8efbebfa1aec7c969533c0ed91544cbac873501df677a027f1fc7e6bb62ad91be09963c3b38f046ebf2cafb2068b8eb5fbfc45a71ebdc5ae5ded4e30604651250b8a18db8f7b10a08e06e8006da"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff", "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "62048fd3ad852e1303d32b29ab761f9d42dbc8158f545c1a245eeca1",
         "0ec29e941c22a4dd49e733b506694701920e0d76f05aa6cd5e1670c9a4d501b35cb065b70953e10aa184bde823b8133d0c409b9a959f102e75031cfcca996103dc61503e84b46c31fd033e7ef694125a2cbf0041b3867e887a34ee46a7a59d83b2d915a1b1fe8f1f208ff5ecb5f6134f8c2f70124d1986bff8a26dba28ea0515a112029ab76b8b77bec6b1b6dfd1cdf7a1d03b634325bf44829176529f4f0610966c3457ea2d5f601a6482d997db2bca20c3f242632ae58f22f4bf5b48fe294f42715520242b33c8957f5afb9e1f87eb1d373f2b95fcaf07b03bf9ebbe95ca1d09c1c6d59e231a2565f087d9a48e1f1ed89dea2e0078a66068616416ee7c36da",
         "85451ca8548530f68d9de6717567a5fcfc71aa37c3b58755ce2e8567",
         "9ebabb17521db0653da73593b6b315786941ee21ff53df6d48c1419c515553240d10dd39930c6fb190cef8794c14034d05382bee8e0d254573d73bafbfcff9bb4f0262477cc9d5280fade542ac516bf755d148a90d3fb8bc132ee35213c2d541e4ceb70f7d3a60665966b81465b53fe2f48c5009ef599a438e4b434d563e8abb835ae9fbe7527f4510f848719a0d2fa8360ca0d883fa492b4a842ac7b83f19b1d247030219ca6d39255f2e939230dbc3e05cc6d298cdb45738b61b3dde7ada53344ee722c3c28444dec1d64ea25c90c03347456a86dca3395fea1c3bf32ca424c5ce70de4fe9d3f1badde99dd60b11255e469d7693b1f54a817a0f9edf1e5070",
         "0b0cddd491275acf6166bc5a52df28c4282a8b417a168b4778afb71e149a5aed52c8ed1a2cfe78a3e578d63ac07f201a5e54448318108da143c4073f2958d84cb4a3dd6ecd14a593422f646b3bbabc07c14d6979edf6b41da8b975d1746824d672a4b66d77bf728db6fcee381650cd7849bfea3b259fbe2881cdcb38541b5685ca8fdb3aa7a7277d437f6ea3c79e634461f8dfbc9dca836492cc6d831e9b6593a383cae90ada2d13e1d491cc482ee96eb374b26d943d9045a692a10f84ce769493c8e14a7683f4f222c7369e6654e4e573acda677708d5280d83a33a6eeb5c0693034a4a8aa67374341f99c72d66f5151a939cd10057789fc465cf7aa928361f"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "40d992e7b563e329a7a4b1701246e7e05fd364902fa4facc3c0efae8",
         "a9eb9f16550fa7aa6943c8533ba75cacafe478da47656e8fe615b7495792da8ab180e306952668ad1363ecceef401a20509c636fd97c664ccceb660905ad4b557687d646df41376dbf447676ab860fba588b5e7b498b9aec815494ffad1382acd0772f284a3c7347d313c7ffe8c5ab08c4d85628bdae69d13b8998f402971aa1b1a507a0dbd799de379d200bbefc71f57f87e5aa99080ffadb2cb0d23b6dcaeecf8655c22e45ef8c6daf158b8482b787d427c02bd09ffcdae20cf0281bd7739de6e9a91bb4c72697a90a2ade148774301f7cd6de22cdcf493925f59c5b0cf2b9ba609bdbd3308d4153d44444aa88e62c51f9be5cff3aefbee068e44ad5a6ce5a", "27fc582b32dea8494f2a1b7a0a81608da65ece26a284861d7e78b5c3", "6d717f88c8c21eeaf06350462f22e41259f7e3e99de5ccd6c6c21e1ed70083640154331e6d7a320c56222231923df5fd344a1726004e14f64b6d2fe0c9746d0f44d48bcc2b34b33b90b3c4e49c3f3f7770f3ec469cbd31f7b1330be42d851c4f13003c967e617a3537865c30912ec3d8ca3c078843c804da5e6130b7b6886c98677c9269727c09471deebd46834bd34d8b25cac89a9f91f175c61dbe055671dc8d264d71551e549dea30b1a9a0e5ec52a842f5c194e32cc0a20ba1070cec69429d86a566960cb85035c9344ce50be5c96bc7b7bcb5f2620ba5790292d8e0744e9f01a3b0033cce143e166d4806d6384da3bcfea3e898e53765f4f159b6aef20f", "9bba760bcf15ed1b39efd53185835bb7085a10efe1ca88adaf81c437872d61dcbd9bfc51bde0c73caf2157472af18d06ef5ca049cb149d1608982dd0e126031daba3dc298f6a8b43605bcfa37bac3df036cbbd583a126a037d79f1b2c591ba4e44a55e1efd81dfca8db962dad4a4eecde0538252df9d411c8fce03c5e1ce638da2b2bdc4e33a71ac6e2b1a9573653b6d73429e9f5380a3001d2d5696105696bff2b0947244ccaa2c526f04aa13239bef800e29fb60f65ea139668daa9eb2648c36a6b1ad4c7d9638baa1cab838d9e63651c9e802948de374865d7d37462f50c08f93a24a6185d3e0ce20a5ac1c713d16d4725ecace93345acf9a482f9e531a59"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "68ccda42a881a961f1f51ea5fbe434f0c41355feab06fb52bb4e444e",
         "cd72620b7be991592f5e23ad76e586678c0e50e024602c76757e38c37c26db0524e3fef9402b18e9ff2c073628d03ba6e19b7d33037b24eb079af6a488f9e071d603b0d139e0463a9230766e8d0dc0482f30a21004b31c1471586e2d49e00b4460793dfb3ceb5179a349bc5ddaebfde5b27dce38c84f86fa4c4e8a1c46c6d825ad93b55124f3f52bc5790eb3383a3670a5de47f08b2808992794c7f6dbd3d7d611c5d82a230b4a573cc8dd1491b4dee245df7ae4cc2b394dcd6ce98e489968cd47bb8b06bd42707c0f0e5377763a5eb237bd50192effe4ed99f097933aacdbf8f7e5bed86ac7f3a912819e18c6e24da407d973245e85a53e9be1ad6cd0777968",
         "87d42fd0e5ebe185e81be9d8df15d8051d92cb42ed17a37c027a3605",
         "554b0c1f2b40f50dd79718d22ac9be91f70abdb83d0c9a26be4d86ce9a096e3769d3a1c6d7be4c5671ca75e05fd049a8b6bc9071c52d380b430838a36cf0174401e77b4495ec826f2fb8512b4d899bae4b5ae46d0a57663dfe7d178cbde1d3f47ecd07b1045f651e332ebf6e187fdfe10ed4bc5354dde016712c38e90be2484e68ec210b214c14049a55f3b6ef0abb0712063146319c9ebc897010604fbca3fe30ac421a4e2ad61519090729ef6fc862b4f112256d5a86573ef21338b76d4a9fdbee52f27117db2ad473783b41a95382ebb4b5b9873987f6df873fe57764ec628dfd1889b17159b43915e80b474628686f97ea9a5e6528df1b4525e7af9d978b", "7e086071b356514b24f2f00aa0be07c7d89d795173e33f4286878d226bd741ab8d5c25aa19eaec2878c89749d652df31824a43b3ac3dbeb6ce8a21eec558dd9d78911ead494311938f7b5488b29ea7128c63b45580ca78e027fd632470b58ce626bbe0be0ea329b87d774408b0613e2fa17df86b6c270567a1fb46500532a16f2cd7375d7dd8b6b86ebfdaa5270349e53247724e475cd545d875d857e07f6a3932cc9b1f1ef41febc03244170ebe843b899615b3143d8cbc2ee5c41140ce2189f9a6b4248089e99652fa96e000043b4b8a26a4ea53022c8af9aba1c23da8a9107ab157b8c7e4629ce7af2426e3e514d62e069fe74534c9e858b0da42eb0b6f9c"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "13fbeab2ec2be1a3c6618d981a2cf14b946a5cb56b93cba79dc5f171",
         "93a5a26413e03865ede51f2abcb60ab48753fa2a7ddf145eb4dc002cc48aa46e62b2991ef1d9d2fdb7acd5c434107030349398cadadf56edcf9b23feabbfcdb10b5f35cd51f789c33703a232e2b3df204a6af3340d94acadb1d0a3cd77889787d1a0e2ff678d538272c37878dcb3ccb1d1503d948e0396af14c9e6a6abbf7eba59855bb715e421d3fdf1c24007a407267d1ab441617f20e3d482d08bd292eafd17b57464bdc158f8b0d7a6eef3db9d781a74fbc5f1b87215bd5c29946de17addf8e7587354ebc2ec1bb807aa0fbe473be6b74c7a05219c48e7f374b88e5f4ebbab641d29aaf692f0fc09dfe48405631d1310d76fe2a5f08b78673ad9e5d4b6bb",
         "b093527dbef289e6a8949864c47c61b771fb4f5a21f7ef377f890641",
         "32338419bf115fadc4e59c1cbc6a8479b9e75bc2a0038fbeab17ac5ca4d00050b525d46cbe44f01ecfdc20ea3f060d39931bc53ae5de7c942299dd2867714e3c59bd2fb4e87c88fae9b21070246c9c975ff77723d7299ad750c9c7917c14d4d57c3e8d094f57ade942f2ee5762f704ae1504ad42dc7e17fc23501e74d403949592b3bc76851ae92ce174d44c6f32c2cd65ee334ce1663c4938e7301d2b7fd3141f19caac89c2be394d0f0c0ff1267384f35bab48f23b37964de674685b1813ad5847eb15c53de8e88b301b081e1b2cff21616a0f870b2e65844270ff73e5b03b3991b1ae973f85fbcd02d9bb1b0e784a6f3e2e64ba344a1d6790c60d02091297",
         "1e7f3180b6a5ce0af683b8f978808a63c1e4a14c016b433055c89b12b534a80da1d48dccce1f2a5ef11d2f9f58c22fe72cc043edd213799b4273c206dd7b4c05ccb7288cd924b49a09c49729257c1677cc2e1484f1c7bfdd57cf7093c6b04369dd23b43df04c1ff142cd1b94074b13190ee3a1ccf98c730c82c969ee4c05f05f741b1620f5d2e5562a18d811be517c48c69f4f2794a735214c5951b50e40224f9a85dcabe120ea6a878f8044fce95231e148721afbab2935fa0b8f6b8e89878a503ba9356fe18b767eb1fbf8e27ca4ca79ffb5c1355aafcce2d97762e3707501340a65241c2565f0048f16ee058411560b46da78e50ef0612a14c10ddcd685cf"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d", "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff", "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b", "2c47d7d326907bd836dd54f58d956bd3dc9a3d3dde00c0637c56f3d2",
         "18d8415c25cce5d69c709ca1a45e4451776b670e7d8a857e999b969d22b3eab5976a04e42f8cce9a3df273364c41e0dc1e8e0d7e811484cc24df3288eea091ac2b9a479e4821565ddc789fb2b005deff09f43fe80a0e45f673ee96a3f9243a28b27d283aed8c0a8c7725627ff53d514592300c75b0c5c24e8c961a79c8de28e14b850ecb49fce39d149d606a163cfac2368d3bd3fa7926a91f1bf5afcf37523b74645cdd4f5a98482f732103d790c560fc69384670ca8055a91d6726dc6591f1fce2e0c63b83878da3a9ad6fa1b4691cfefa281568a966f1447d7dcf57a92d8d401df51c759d614c9e6d6c5c2838b9d706c6e22103931116da5bd9cc6ad91505",
         "2397f8977506adbd9a99838e820b6b034cd09fd7f3bdfe3eb91a947f",
         "bc78012439f4f6ca2b9f9673144dd17a45dceb0bfa7cf296319e38e4d64418cc7b629fd733137553bed9306a14c1d0479d7cf3666bccac038539cec44c4bdaa6201701bf48f45aaa0dc7a880b65ca3a69089e9bf1a25ab34108f1dd323e2ea07a3e31274d3e6a05c43c0896f3f85edda97767c79521a8a857f12aeea039cd8c9d611d3a9b8b2e394c8e8e5bdadbb727a10e100b2abd726c35800e7e91277a5f824ea9fca6ab9f3ea8d5c39a8eb975f20d0dcffe018499cd1352a9b5ca84b2d1fb1850baef7a681614413687841c56a47fba15929a091c21f7761a12763e8ce5631d8875c042c3b5ce2a09a1920484a62ce50588f88c2b239ba29119949bf2281",
         "97fb7ce73adc55e221acb1863b56eb97f9d0f28792f26b61a71addd98017e60fcf7d33fcdcc2482bf6c93c4a8fb8e7feeacf6c4de3d8de63659b4d8c57fdab1d89d1510fefbe3a6ca013ee61d46a62afb4b81ba6389f09d14f26ac25dc22fda2bd8c596b89fb36f850ae2491545b41e5e575d7e0fa6fa4df0f568203d8a1b38fa2f6e03991f9774cfd1dfd1d9171c189768856a3a31a84555d5fa74e866db88e24eda5dc58e6f2d1f6faba17dbf838bb97682123c6855400c1381247f618c1451380f4ac01a109a4eb75efc8b2577e35f98fe1d1d9e45f0cbcce15eeb8fcce59264e76673dd432a893a000557d6480d76ccb32484d6a298503db3e93535e61dd"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d", "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
         "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "93b6dfa79f9f48c6fda84b8df509e08d5c41b851244f98606063492a", "0279da2ead7154e13eda84ea17c35586a5c6d6275c069d6d5ed0baeb3965f6bb73e3b9e37b41bca43a80076fd990832d3311d9f14d7b9e2c73284834a413213049deb3fff38ef7dfc26853d302f3011c18f3321f1dd3ed739e750e02558e4e6f4a27797e3ae90e3ba0126f620b0d59260483aa8da7249f836f07bf9644ed5c8ea4eee11c96612b02bd87e3f156521571c4aa158ab415d64ee0611a9189f20638b7db9eacd12560809242c32f2c250ff840e64c5f7912d32280708f6c32e7f989f1369820e2cbd673af0aa8df9eb15aec22114d5c489864d11faad262d3f476afcbe7d77c99d59571e11bcfe3e7aaf6053712df63a840d1fb514982857c222966", "ac46d9896525ec5e0720519ffa423a7dc78b6e29bb26c2de573a8ff7", "02fc5c032c938e3155175ba7a51ceff642fc408dc262859f49603154ff28d958ffd2d47e57b2ef1be2bcca2fe1e5fca26558a47a432fac81de2c906d761b02a98c5ed225d6772aab6f98beb7de684ba36c70fdce201cfaa63d6b25a6b60603f59e0e8f460fe93eef3979bf5b27e5da6c22d79a7bba06d7703a1249e533982bbf654f4d76fc45c6965cbf30725fdb871325dbe70f0d14f04ef9127792482a88eac4296d28df4d9f0a2bf9b8ac7603846624bf4860aede8730954f80f02345b041cce2c8e20427d4ce6a023573acb1319f9b295c23325b60572970227de765944614eb1f00a65def8c79babe9ee0f893bbe960611b82e19cc31ecb208548f06bb8",
         "abb7715d16b6b47816688584b8bdcf7ad4a2211b58517fc28fbd1fa6c46b183f8b786242dc6bbd90088c54483d7491c49f5ecd7b011ab4549c84b2a3bcc07afb3810d6fb410fcbe6f3f5b7d0b1dcd1a1d36d435c4588a152bf38cc22f698b0d7c38a0b6d703797648bfcc36eaad2880a795741972c7ed7a5be435505c8e5792a8e262b6c1383bbec7fe24269a7afeba36400a6b59f29670e203e88c4745a23a6a140b76c283ca74e06790d47cd37e56ef459a92f54827a611185956347e67a89e1d4291be7ec0df94f4ef28cb92278763c8abdb3a9f7153005811a512257c16593f01a7e28006639c6186e23b3ae961f64d4155e34ca59241fafa9a58b4b80ac"},
        {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
         "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff", "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
         "763d133c698fc662f790cf636d78712f00ba40eb2b8b20bfdb581f60",
         "885520aaf629e8ce594a3c493fb58df778fa5edc0ba379e6d33e7c8839cfec659e2adc63bdf5f896fbe554e3df9632a1a5b71a836871d5db84920011c393245f0fce943d57a15891586db60a7cc41c82a068dd77511c63ca3d37e9234cc753aa3132e3ccfba70a54998354f6385d2ed8eeec2df678087f31a7056acd72393138cffb3ccd0d95318dd17884217b1cf18fc8f13695a05e0a39f74e3e5411c8a85d5797b0f9c23b547fb5a991e017e7039d2669481345412f9166145cf199a5bd0ed3ef2c5e179c68f10f2ad6aae447a4d2cbed455d8e86707939521c887f42da7fb79d4e7778711a859382eaaf5cea8d085e2609ee7a442aa54844a8d47bc4a00a",
         "0a4d2cc4d45557a9640ffc0bc4361995fdcdf371d783cbb0ad88386d",
         "c0bbea890abf71c1c665c14064b8bfaea5df1bdc16cd5fc63b61ec90cf971384f3b1b7e8f718a0495d5006882cfb9ddb828227022f799022b956d0878c41c86ad54c1a5c47ae450c5f7edfb516944ba078b5dc6d8b5a33b9e92654146a10d0e2bb9d001546d94b055c215f8c30b496ff0c9b56ea75cf50c52f26ff67bdf5a78941319552db7f5f06f58862889438bed4e589d4902636b27e9aafc135ec0555e0512a6c7bba935f1598f6a2d2f95d36278a0ef8f94a985cb89e05d38e37c2b1e690f7e90eb1a6f215842564274546d8fe0294067a632ae3af9af7c5d4a8057b673cd5eec4224f54018ba25cb0fab91d3df8b8fec01849142c0dcba1448531af44",
         "56d05feed5373450a4e60585ad6ede13ee4e87f757b115134c76e54e3fe96dbb76640d347b71e8f488cda345af5fde5bad8e3abfa786d467b38ef8b9c7a5d5ac38cbdb07515af6bce9c3248d8476bdfde3f0b5fbe797dc41c76f61f4f1cb5c52a2beff30ee9315cc3f836972db5d50fa9b57b1941dd9877929ca3657671b0187ce97de4f146c0a26435732c25d9503b8f6d334030006a40c10e8a5c3c92b5fe198024a4d7421360331df3b6838810f42390c42152517b84fdd10f99c32b22189066ab0b276db60c258f36add1d359a5686b7b9ed4309d628e0b06b6d127bb94c2c6a042e78efd228bb43e65e8f81d132c39b9c3a3dfa4f3878a3922827c1bc86"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103",
         "99bf1768efedd2a5bbe7c6dd15ac9782609c18cbad48b69f1b1156b300da5173",
         "4b16bdd9f9b72a1cd54c2f732e3ccf584ca68591e0b10a1caba045030e6edc936536600a5765e91c69cdfc1066767d501a6b8054eaf0ea046d3c4415d3d1d2845b4f4173a608ff50bc7a717e28437855f5f9c06177981d8e6b4b077cc01a43c781f735937c457fc74270e6a5d69392e0a6c8bc1513f4792ad8a3b098226411e06ede834c48c391cbe1479e066580d2dd1f8065a9fc0903c5afdf13c7e22917ccbef8693eb35f4366501c5c88fa029d943f0759fa49f98b366c18694e8eca06d34396cee39a52a17952e285e173423585c708cc642e01de27f5095b7390f6f9f87d53929a31a40e5b9791981f2567dfc33c41905a93b288c0df13368b744978d7", "203b8933badad437d97ddda3d243120df54d53f06b840cefba73405b68468a92", "07ce314e48cedd4da9729fe5adf5d4c52ba1025ed362fedb2519c7762aa281d8adc8cd6ddd297e50fe69222488b49732d2064fd13261e04d18697b4c266acbb7d9adfa632a2833b68e926e7b4d013aeeab936a807f71aed4f2c7a6197016138681ecaff0f990def56ea7397093d39a86a46add91ac116b51ac1bfafba6294c6e7e5541d638a102637a49d79471da926ee3e53e1ac54fd40d2867902f143ceff707c07fad16cc79cdb9104a22eb16ec2f0cfabd91da6a603991d8ef7b2fc4cecc933376334c9d87424ea0495bd0c6d73757657b305874d6402c4bccb081dad685640af9616776d7d5164f11c2384b3f8246d8983caf11b1efea43e2098c0564a7", "b44c0778b094874a8158ace3a6e4d8ffb8ae1b078b06912f6205f1a339de2c9d25afa4430b5c1761d699340800266a8466e76244b9a21b6eafea98fb09f50c6c06c8126ed6fde4a1f9a4c7a24c6989b6e4a9f0ee487e545f55be805ab4ddf32f75e0787a456852d4e8809dbce0daee60669e9ea5e195153fd90ed9eb7173329aa5775f90c708c636f12f007092e734c984a206f9372666ac341e7e906491d269463fea2b6ebb7c9c16646b03490ca4c7387eb9d274fac77b410a3bff0d2e532af75c89f647d0c76e945f480496cd9c44fc4efb151c718ed6663b66a8c5a07e83f2bda3a7d20c7a6640552d1fe69ce5cf0482c3aad1f295b9e1ad0ce5c4b872ef"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103",
         "c9d7bebc4cbfb2ac37dfe2d8ad3d040cfb8ce1dc57db10364b94d74990b982b6",
         "6f77d81414d2e66d2dba3f58d7be9d3846470ef2b5c7ae42c1b5d4733635220d127e28fa2132d3b3ebcceaae5b361e524d63de8c38a352c6722333176098c6473075e2ab29f999b1c73970f40d73e28cf04083441aa65b4c930df4221e86c6d7329843ddb52af5c54774a804e7d513f7af2665cfc8ceba97a793d42502a3595752d1e7e490ad187d13da183ed212f339d57495bc1d424cede5b780fc537afa942d083a53e5661b52cc69082154f346ea4f90f9b5a9e3f8e15d5731cd5a52eeed673ba8857926d826fd55a4b9d9155f37830424d7a890bfa7537b6ff0a9a2ddde6706f7821cb210b27840fb05df7fa0fda984d156160ea72c57f835382e560328",
         "4c48d6ea8c9a94d460cec17d0e3a26fb2530590634db6e0859b5c8d77c76ac50",
         "b9a2cb85daea8f550e41b05d7d892dbdd2c4f2955d29ed82888b87b26c9ee727b9adbb4c9d2a255b2516fe3dcb6948701dbdb16746130aa671d0be2232bf1744b5a2306eb72a6bee87c6f4236a0da1132ecc000adfe0092f98696b3566b8e76672b863984b8c02a65476049dc3cd384d725127a7ffcb33bdad0c99774db8f1221bc7570d251276460ea9a3df13cbfd775014de94cd634ce18b6714e4f655409098a2404768d1dfaf63fa1a7d20380c222905b5d9467b25e4cffec5f4c5c356e6b4fffa893b76ff257bd16b4b6e7b5fa598284faf0a05f23a9e01218fda21bb7128203f11209cd2e3d254155edf2b7913b073c85e5975de7241eab078309d7d36", "40191f4bafbd07147f0fd03bfc6823b4d7e77339cabb40c98fefdf087d6e812ce91d39cb4a8b78c28a96f38dd0e0dd6f473b0a50bee346b8dae3eaa34a1c54a7af46057c9a6f8ab9addfdbef0287327002112832ee1dbb20d2fb0748a159036682170237d8e83b6e0dacc9f20c9dcad871c575ba2ee504b3caf3195e56b29be98f75fd3f3e6547e270f5317798da2ad2fea486f44e2e9e298fbe76eda74ef0c0947ad1d0a678af94709624fd3e3913759ce34ff57e2ffe0c047350dfdf93ff4bac5bdf8f3f676987013f1a971716e9ac78f491a332e863888eb0925b79fb974f184b5c7685390b93bf40f688b02bd2d07292515cb969b9c52ad3797dfca16fae"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "9b14f9773f0ebdc6077efbf61ad0ff8487d0d7c0fb5b59ddfc6f5a2decc9271d",
         "b9a7e60623b61b3a2240a75af45ccff21c2800e0cfe7348b49fc1febaccc1ef121fb40781c07b7bc659c45702059c6a6481ee770a89dd70cd8c61c1150bb17c0d424d98cc5ba61213cbd096525dda52c41af7c9e9d536afd203c642160f8b69409f68c0e9cf8222020eb95917178e337fa9cc588585ff8c62b9d76de8b5da13cc58226c9df4cb80e1a1aa09f1dafdcd67a8ca8c5b266f1a3c853f6d526557e97c94c9e063fcd538f08c9db00710cb90e835514c70cd42eb5d865b49c269750fc77e4360c8071d7f9d65d2d874fcda8cd23d8ef3b2e904cc01d80505293d503ce92558171948824b3b0fdfa8dbae68eb638d3619a51258a0701e2176143eba8a3",
         "47b5bc492362a4c7c0bf8ef51b3a033cac7e7165150329b5c23395a63d6fa84a",
         "1a7175256874978e73d5c3b26842362005e4dc50d51f69413c20f2d632a9b35e7f6a64810409d8f78e64af8dee42a8b63ae5a0cd76c0ff5ad6fb7462ac5890de4051110806f3b2a63c2918971bdfb5060896b5698d1645d336d1cf5a3e90538855cbc5462a23caaa83f066a1f40240e843b5794d88ce938dc9712f91d233e92dd2c5dd076da72f89ab08fa9f5289ef6dc8f584933fcf5943ad4c8b81b6021caf8eff4c23bddf5bc4138b0f3cf2e65ebbf850d9cd81ef1e20e69e997f312020cd4feabf8013eec9f3f66511a8c3dcb0847e6466c5b5a5f919d7dc4f6a9f863365b6e016bf1e0d40ae22d3b255042610343483f99696bb877dd4908c4bdc27a492",
         "7b0f5f0795989f250393d3c38aaef1c5768e5eb72607948c0465583a9189951cfb84fcb64bcdfc32786a7753460ff7fb173f2de0a2e6f5b82f3c288e0cbe503033a8f51a6a8cb4a9e47e07cd82eaa8a80472506c6aa87137c4fce860552d79a9f46000b7501442eea4d3a34c94f90d8bf98bb45f4bb893f974ef2cd29371b671cf219eddf08f911eca6bc8d56d8b5e7acd23ab79d159f695af8ebd3afb69c273c9db1c9074476ecd9b8882a95d805ed9fd2ea19c26f2affe9584190946d64885b5fe914236584ad10700fadfd934716e3cadbebb3a479332a6bacd547d104eb534716fbe34de5fb10dabbf2a3e584b215676af24e26e2f3d224210ac7b333389"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103",
         "21fbe182d9e7e3e5c298f0c2c282c5f6079c9861786a17f4b593e9b0d1495b53", "0404d8df34aad60bf4ec5b2780f612e4b055c95f8829e5d34f784701b8e95ee8e5000e537e84dd382ffb3598dc082abfb9249fa98dd1503513a9aba6f6c637b8a25e620d2d561219f4ec3cdee0f4e6fc017f21e88cfd56004e74065c952738505ecd29bc5920dcb042139af9710ae6cafc8c8211d097e010337a7972348cf0cbd2db760fbddce7798cdd45aa650ac34c9a3e991e6d2cda5039bba14a6da8aea15e1f61530c25d6dd6df55747e4229e646cf4e24695efdf6387f5c1b9bea52d83f702cfdc6147181ee6989e4d89e0287d292700753561e4fda2e29bdf2f9d4bffc27046bc24b2a9659e263b040c8e49a4a200af860772382dbbd1cd2ad7747144", "4d956ff9761978890340133f774b2380a242f858772929249d9ccad06f727bf8", "41f29770829c8e0f1df630fa7312d625a8fb8aa8efdca7fe1b6894f3570f39d4ae46ff9491b8aaafe7207f84e9eb75c4e7eb099c33ce72db33282675eca6930d7f261c6dc061c39ccc01caafbfcca1cd733de1adbb718913322c6f7c7c467fbb9d4bd60aebc0dfbe232d0a7deaf57ceb054d5893f8a72d89599e10e1682ae2b59d746680bd9b1f4cb2cb1ebe649a3aa3cf30fa8fd1e212a696ab5a115080a817c3aa77e56b46f503ba35cb9d3fe09092f0ab9435c34d94ab7e1d0a736165d0ba9cb696fe41f320f6b925ae05a4a2f9333058f4339426d34f8b98ce96b587a512b22caf0d6dd9c027ddd8c508faf51ec0f3877c248c5a9c5e3048eb810b3e659e", "3e8e0e019ec2a3b71a3cd3b7099c3af96ad8c96ff82e823795d90c95c0c3b1954c4df6a6877b08b434f34479caf597e55e804a42b835f39b1a0c2069297e554b4f039db918172eb70210b5553275ad500ae357c5a370f15d2e8dabde018a26b1af6e9287ab94d8353fb5e6d62fe8715cd5cd226f2d4e554e5a2e1516b9923b7cb5211fa4a5adde16ff9d355986c8c523ffe293866c9ab7c04079ebaa9964ac2e1e863829de635f7d1ad65d747fb417df6466341fdf3f9511c53a2d588fea44b18e7efd99f291ba55bd7f4fac97ef654dabe17b738ca4bdd6dd664ddc605bfc7af9ad959f1ae6223d95344c5cb5de3fdc37955441c98823829bcde555ae89ca20"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
         "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "5955c0d85652e90c16ff7edfc29b65f5600bb4d347d443bb55e1290831d7b279", "8a38f0608acb982f235db8ffe1072ee2786645e07f0a3b7e872eeda5ef7a28a32e30582f9e338497da1ded14de4665acce65b7338fc3b6ea4fb7f8ef2f341197a3438539a6d5b08726b0361406c21d2d53a43e486e39fcd567cab124c9b3ea9b3a8335f283c67cb150b3f357779fa759f4a509f7839de572de7e89fca79be29e6cddac4274c9ec73542edf99a2099a313d4ecff7755e30f873712e6f598a568a73d66229505ac8459f19ff05f117b11f65141113d95f00de3f8f796bf7adcff502d1f0cea095a1ec93eb980ae117899fca057b98ffe89c4a680cdcf09b0c8310d8c6a76b54561f6e2a5f98ef98de2495c239a2b7ba9087570df9e85887ca1900",
         "2c55162edf332498f817eab0d0d86b5c75b4528d9d1396192f7c4e8f39362454",
         "87d93559cf6c5a1cdfccade4e3f14adbe76d110b328bec38c51e2329cd7e98bfae8138474ae7c603fc1241a17a1294924960344ab019ca00a6c502549ede11c2aa8db5578529f92ef34d0fe1434ea9426a9892e046cc7fb0a722648af36393176e07e1f3674f443911a861c1257252e8c9f688ed18ef12821843d4af4d1e011c5c3c15f576698bf6bfe0c85de1d930e1b2f248a4d617c72bc7f203eb17ce0e3cb1631cec631b41b001c82c23c953e0e531444c73a350a9d3314fc6f57cc0b2d288ed1c1bf769b1428d7ec3b3ead54b7a38ff86c68a514edb8a2d89ccccc251c5362e1f0307cb952a7f152c3833d3102210e4f49f65228743e57d41b47f0c7303",
         "57ef5894c8e88671c5aa125ea8917a799bfaef87b2d1368328e73fe285feb6d0aec8039a8883d7884ee25ac31a885dd2995545a6432acbef94d8e99429bdd61788f0da4a1590524f7d24ddd5df2cee9af25ed988c7e0b29898587bd6914c64f5c1adbb087cc708f4cb6381bd278c8bae410f92cb062c8bc5445f732bd54c1a77c1a02f4577618aeaf658e2c85744b284f4d54f167c71fc1e65cdeeab34e5325d2c95ff609f4c88bea635e7b98cf9d9207abc0c5382d920d74252acd536b8ad332c995513a2cbc7a17b212cac63dd8624ef83f7f517b41826c2e26c3686ad61e9ff069309855cda8826e229beeba5f0c13ebfabe3ca5d8561a2bd3530b936d42f"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "cad5b21ecc9e1a6b48a8b03b0df2cfb18a31b5c5d0a416fd2918d38bcacb061e",
         "a4641db09973ce88a2b3415230b355481175fefd2cc79035f0c501a79950f0f45fc9b98b19651a408e5d036ecaf3b863b7156dd88f381e550b7fb6e18d8b6e220050dffb33952c4246d972bde0d7442454fdf4f2fb9598ecbd7d9edcf746f02510329677a7173fe965dcc20241b557b1d9fb4228f91c3e524b7a5d8ad7eba85f4d4903a9f3806c537811e6a8f6951d0f9061c8dc5ed44f879fdadb6e05381a4441088368b87b6d262638d0c507eb6f3d0580d35c9ec8fe4bf2f9d5f55cb7e82ec3097083998dbbf5c09357937f67dc307b36999f1e3aa3a469cf5b8dc33297719bf1b07b6c2031f69c2689598894c373f2c1bfdc074d32be7e665357159ece2b",
         "3bf1a562acba0c3d3ee36528aa98ee456e4e1161852c4fdf9a42a67354ba1ecd",
         "17a573cf63bacfd79ec59fab54685b24ed632bd16f6e0131ea3a9bdaf2914622aa94f15ce4ee9919e51ecefb3345423afe36c9a38ee8c6a48f4773aa3fbada6eb332b1657ebf865b1632be847fa1c33a7fe6e699af6cb0c995344a369ebdad97b21d168b0e3f261df1aacddfbae1fd9784137741d82dd9df7ec6d2cb6c45fe8894e24d55a983cb9ac9820ffde0badd45f3f00300890fb50ae5718daa029b9f7f985270b61f462c7fe60e00b89b2363d8d58ba4d11b63729ecc3226c8a60e7711dd5f635019397a32965b3753bdf1f5d51c669dec41aeb6184de7d87aa57c75c9bfda44a2d6f65d3cde264d6a40d87fb290b15c943464d1fd4b807be35800ffb3",
         "b93ae6dc7b01186939e3a897707ed4923a83fc08e1f9b777f08d267d10fc34ce65ce95540201f0f52558f6efb72287a5e0a6fc53af96e702d1e162775679b69ede31a05217868274987eefbe2015f66953a34c4b5390a5e671cddba5977991b187b326caaf42f407f14fdadf539e70b4c20859981e11bc7892addb8c1f701f487f08a80c5d35abc83b889794073331ce6ad1367d3865f7d225e8c828774e7d56c6ff947e4018223f56b1beffc0079fceb965cdb6519416a709831e919a847b93daf9b15db288d7697a389efda0380c9d411c3bd3132a0e04791c5117a49e68444e2ecee98b40cbf7bd3ab22a31ac0a3d12c391d28269a46670a02bd34534f0bb"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940", "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "3216fae47159917182c09dc08fc11c77d8921be4fb6970d6c095027e7ad53c1c", "4ed0b6f75af48a8a8e634d1cbe5c00a771d090ea1746a397af8317374429969ba2af6c4b4d2dff2530dd86f6790d4d0268e955c58a725c9cfa7500d030d12fa9f07884b078305714426dd70a6a572e828567662c48bdab14543a3d62f8f1d1866859f659581bc819d9e93ea9557c7a9ace63797ec2b09bbf68987c6de4cb29d588659fe84d4dbd1360d41c315ff890adf03f03121fde4df9366fc8f74220efe76dd11eb609da67b416971009cf5a176957173d7824243ae67e1d0e7a0e97e21b1af1b51e06320c04be6d1ab3209fa89781386ac538d46717907cd6cd9d68627d171ced654ac7343f2dd3dc255aba472cde506d62620c72a2b026580b19f9f79b", "17443b1a3115da56fc2372bdc755b8aaea8cc1ed636ccc3f6a722e6dc0642fdb", "738921a16c7395f3f2b65ffb656a7c9c95113145e59c5f19e619511badd39526535833ea220ad8aa6e369925202f7d471750852bbbbf9e33312ba77d6a47e72181c2baacb80973a9fb36144c8544eddcb0f632b8af7463ab27340c9ca96f3991b7f484a77216dacf6d97879ca4c531a812a9dfdbd5be0e49e7989cad7825b4426fbc5fa0301f882543bca26326af5e3f1827abf8eea9601cc0d57d42fd30be3c04a897b531b0323c33a67a3931cfaada84cbd0d74f3ee40a6a89d8d70a90b6af87516dcf5b7ff79031b571f53aa95c13aeda343fbc83072cfccfbde6594abc295b485b1c54155bb725e2d0cfcf7e9a87fe5aa174ff917c1bbb90d72b652de5c7", "a858d8b3928a49a094d178177e4d280e0506d83bc4382c08b75ce809f8b2fe2dc6a714a684edb56e788e1c3dd0f32e6b097563162dc7e21cf6389d90a5d127b738f8f3bae9e6310e21b19964890f8e808705eb5e5a4e87a847448dfb96872fc63539d6b64ad5712e833db5e422bceeb25bd55381a894388d3efafaf9a292c42973f40e878bb2656c5307dfc61d0ad228dd19f10b4d12177adbdff03fcddcc521f56b9f4d92a4aded5afdb4adf76ceaee135bc34bf5dbe3e6ef83d904bb09d2c06fe488419e1246226cfffb51713217e1a393640d78114407418d5c71712f695e96d529ff98541381f358c0005cccc4c8d97d9928ab97a6c14cb6356cdb70b96a"},
        {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699", "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
         "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103", "c66b8c351832ea01a5092c59be148b499a5951b78c8ec3e6eea84183fb5f5ded", "2e656f3bed7bb2d71da7ef3d43fd031bde0b3fa00c718ac96b1a1c61863a0053cf84a8bacd5705a5a2e4d398e1daf3a80c995dcbffc682e3a44c2c191d3fd8155f52eea3a9d7f420d7a3557177297f5b87b9429d910277ee62757e2bd3b3f7c1b680bf6a9971116560e1f91bc902e31235933d14df5875e06c11946d133bfcfc9944a4f46501127a9b850febb32c86a8de6eb8e66f3c8abd2ba3ecd190862a83d120a98c64501d92ccde1c3ee376bdc99b55f53fbe8d8969ff22b421997b6a88b6c917ffd11f29a22e59377e750c11a9e0e06e3e3b05441aa2e2ac606812f8583ff0fd8a02f45fe0a1024d9f8884a6987ca81e2226736e239bc96194b044dc73", "3d802f12c01ff8f0b59c08b986ce7f8472336565a2151d3556a48813bb8046ed", "176d1ddb56ada49bc1582b2774065b83d097f80375be555a15e0a79be5e87a3687ac0c1680afca79216f387856beee345c5d3c6cf99f72f0fe0adc694ed0257efdfa96b6061b3c87cf30907ab90c26161a7d4d1a6130ef7529f6e2fd131440f9c87b070bec8e6d00d7625b2532147a380ef80035424df83eeb6ff8cd334ba0550232d0772ea326c310d11fa016c434e7dd806a2b980740cdb678d50a03b4114a148fe3d57eee2796e7493541659bcd7181412d461c0ca726343fdf2c841d8953c4c64fd346e096f434e665b21eecf86f0fa6fcfd3695cbb7dbdb8c064f6dc09dd33cb28ac38c3ac9bf5b02be4b6f227ae8e7d9d32b3cb827f4011be82412dc5d", "492258710fa5a3f17908db78595e00d329c7e020c54cc19be86ff41c0ed8838f6e797b38bb239e601dc09e7faf0ed5df534939ef5dca0fef3b50e87d0cf4b9f202c24df7922596378763f30df987d2aa4453fbd473e835db268bec714bbc1d43ab9f2700c3b5227fa653ebdb6f69d35a14cd9872d512b1c58542c976f2513690bf214ed3115d0016fb25cacdf6838a972a54dfbe1fab44c6c8c4be0d1f0949a1bfd1962f3c06ef0acfb3913939d31ff4b15ff91fda318332562d981cdabd52e9a12ab75159f434d7bfe4a071cf9cb646e2c6c9e71423f039b747e332b6c5dcbbfbf6ebfc1885915561a70306fdb03c6890c05ade9b624b831e4612b0dd013ed2"},
};

static void SDV_KAE_DH_FUNC_TC006(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();
    Hex *prv1 = NewHex();
    Hex *pub1 = NewHex();
    Hex *prv2 = NewHex();
    Hex *pub2 = NewHex();
    Hex *share = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);
    assert_int_equal(ConvertHex(test->prv1, prv1), 0);
    assert_int_equal(ConvertHex(test->pub1, pub1), 0);
    assert_int_equal(ConvertHex(test->prv2, prv2), 0);
    assert_int_equal(ConvertHex(test->pub2, pub2), 0);
    assert_int_equal(ConvertHex(test->share, share), 0);

    assert_int_equal(RandInit(), CRYPT_SUCCESS);

    uint8_t shareLocal[1030];
    uint32_t shareLen = sizeof(shareLocal);
    int ret1, ret2;
    int cmpRet1, cmpRet2;

    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPrv prv = {0};
    CRYPT_EAL_PkeyPub pub = {0};

    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);
    Set_DH_Prv(&prv, prv1->x, prv1->len);
    Set_DH_Pub(&pub, pub2->x, pub2->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey1, &para), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    ret1 = CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen);
    cmpRet1 = memcmp(shareLocal, share->x, share->len);

    Set_DH_Prv(&prv, prv2->x, prv2->len);
    Set_DH_Pub(&pub, pub1->x, pub1->len);

    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    ret2 = CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen);
    ret2 = CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen);
    cmpRet2 = memcmp(shareLocal, share->x, share->len);
    assert_true(ret1 != CRYPT_SUCCESS || cmpRet1 != 0 || ret2 != CRYPT_SUCCESS || cmpRet2 != 0);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);
    FreeHex(prv1);
    FreeHex(pub1);
    FreeHex(prv2);
    FreeHex(pub2);
    FreeHex(share);

    CRYPT_EAL_RandDeinit();
    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestPara SDV_KAE_DH_SET_PARA_API_TC001_VEC[] = {
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23",
    },
};

static void SDV_KAE_DH_SET_PARA_API_TC001(void **state)
{
    CRYPT_Dh_TestPara *test = (CRYPT_Dh_TestPara *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    CRYPT_EAL_PkeyPara para = {0};
    Set_DH_Para(&para, NULL, q->x, g->x, p->len, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    para.para.dhPara.p = p->x;
    para.para.dhPara.pLen = 0;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    para.para.dhPara.pLen = p->len;
    para.para.dhPara.g = NULL;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    para.para.dhPara.g = g->x;
    para.para.dhPara.gLen = 0;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    para.para.dhPara.gLen = g->len;
    para.para.dhPara.q = NULL;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    para.para.dhPara.q = q->x;
    assert_int_equal(CRYPT_EAL_PkeySetPara(NULL, &para), CRYPT_NULL_INPUT);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestPara SDV_KAE_DH_SET_PARA_API_TC002_VEC[] = {
    {
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
    },
};

static void SDV_KAE_DH_SET_PARA_API_TC002(void **state)
{
    CRYPT_Dh_TestPara *test = (CRYPT_Dh_TestPara *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    uint8_t longBuf[1030] = {0};
    uint32_t bufLen = sizeof(longBuf);
    CRYPT_EAL_PkeyPara para = {0};
    Set_DH_Para(&para, longBuf, q->x, g->x, bufLen, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    longBuf[0] = 1;
    longBuf[1024] = 1;

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    para.para.dhPara.p = p->x;
    para.para.dhPara.pLen = 95; // 768 / 8 = 96, 96 - 1 = 95
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    (void)memset_s(longBuf, sizeof(longBuf), 0, sizeof(longBuf));
    longBuf[p->len - 1] = 1;
    para.para.dhPara.p = longBuf;
    para.para.dhPara.pLen = p->len;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    para.para.dhPara.p = p->x;
    para.para.dhPara.pLen = p->len;
    para.para.dhPara.qLen = 19; // 160 / 8 = 20, 19 < 20
    para.para.dhPara.q = longBuf;
    (void)memset_s(longBuf, sizeof(longBuf), 0, sizeof(longBuf));
    longBuf[18] = 1;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    para.para.dhPara.qLen = p->len + 1;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    (void)memset_s(longBuf, sizeof(longBuf), 0, sizeof(longBuf));
    longBuf[20] = 1;
    para.para.dhPara.qLen = 21;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestPara SDV_KAE_DH_SET_PARA_API_TC003_VEC[] = {
    {
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
    },
};

static void SDV_KAE_DH_SET_PARA_API_TC003(void **state)
{
    CRYPT_Dh_TestPara *test = (CRYPT_Dh_TestPara *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    uint8_t buf[1030];
    uint32_t bufLen = sizeof(buf);
    CRYPT_EAL_PkeyPara para = {0};

    Set_DH_Para(&para, NULL, q->x, g->x, 0, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    int last = p->len - 1;
    assert_int_equal(memcpy_s(buf, bufLen, p->x, p->len), 0);
    buf[last] += 1; // p is even

    para.para.dhPara.p = buf;
    para.para.dhPara.pLen = p->len;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    assert_int_equal(memcpy_s(buf, bufLen, q->x, q->len), 0);
    last = q->len - 1;
    buf[last] += 1; // q is even
    para.para.dhPara.p = p->x;
    para.para.dhPara.q = buf;

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); // g = 0
    para.para.dhPara.q = q->x;
    para.para.dhPara.g = buf;

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    last = g->len - 1;
    buf[last] = 1; // g = 1
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    last = p->len - 1;
    para.para.dhPara.gLen = p->len;
    assert_int_equal(memcpy_s(buf, bufLen, p->x, p->len), 0);
    buf[last] -= 1; // g = p - 1
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    // q = p - 1
    para.para.dhPara.g = g->x;
    para.para.dhPara.gLen = g->len;
    para.para.dhPara.q = buf;
    para.para.dhPara.qLen = p->len;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    buf[last] -= 1; // q = p - 2
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    buf[last] += 4; // q = p - 2 + 4 = p + 2 > p
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_DH_PARA_ERROR);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestPara SDV_KAE_DH_SET_PARA_API_TC004_VEC[] = {
    {
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
    },
};

static void SDV_KAE_DH_SET_PARA_API_TC004(void **state)
{
    CRYPT_Dh_TestPara *test = (CRYPT_Dh_TestPara *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    CRYPT_EAL_PkeyPara para = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);

    para.para.dhPara.pLen = 95; // 768 / 8 = 96, 95 < 96

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    para.para.dhPara.pLen = p->len;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_SET_PRV_API_TC001_VEC[] = {
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23",
        "1ea26e8b4b0061e1dccefb2f56b0dadd9d0fc297e215578823a07e97",
        NULL,
        NULL,
        NULL,
        NULL,
    },
};

static void SDV_KAE_DH_SET_PRV_API_TC001(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();
    Hex *prvKey = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);
    assert_int_equal(ConvertHex(test->prv1, prvKey), 0);

    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPrv prv = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);
    Set_DH_Prv(&prv, prvKey->x, prvKey->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_DH_PARA_ERROR);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeySetPrv(NULL, &prv), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, NULL), CRYPT_NULL_INPUT);

    prv.key.dhPrv.data = NULL;
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_NULL_INPUT);

    prv.key.dhPrv.data = prvKey->x;
    prv.key.dhPrv.len = 0;
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_NULL_INPUT);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);
    FreeHex(prvKey);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestPara SDV_KAE_DH_SET_PRV_API_TC002_VEC[] = {
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23",
    },
};

static void SDV_KAE_DH_SET_PRV_API_TC002(void **state)
{
    CRYPT_Dh_TestPara *test = (CRYPT_Dh_TestPara *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    uint8_t *tmpPrv = NULL;
    int last;
    CRYPT_EAL_PkeyPara para = {0};
    Set_DH_Para(&para, p->x, NULL, g->x, p->len, 0, g->len);

    CRYPT_EAL_PkeyPrv prv = {0};
    prv.id = CRYPT_PKEY_DH;

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);

    tmpPrv = (uint8_t *)malloc(sizeof(uint8_t) * p->len);
    assert_int_equal(memcpy_s(tmpPrv, p->len, p->x, p->len), 0);
    last = p->len - 1;
    tmpPrv[last] -= 1; // tmpPrv = p - 1, Vectors are guaranteed not to wrap around.

    prv.key.dhPrv.data = tmpPrv;
    prv.key.dhPrv.len = p->len;

    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_DH_KEYINFO_ERROR);

    tmpPrv[last] -= 1; // tmpPrv = p - 2, Vectors are guaranteed not to wrap around.
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS);

    para.para.dhPara.q = q->x;
    para.para.dhPara.qLen = q->len;
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);

    /* In normal para, p>q does not exceed the threshold. */
    assert_int_equal(memcpy_s(tmpPrv, p->len, q->x, q->len), 0);
    prv.key.dhPrv.len = q->len;
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_DH_KEYINFO_ERROR);

    last = q->len - 1;
    tmpPrv[last] -= 1;
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS);

    (void)memset_s(tmpPrv, p->len, 0, p->len);
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_DH_KEYINFO_ERROR);

    last = q->len - 1;
    tmpPrv[last] = 1;
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
    if (tmpPrv != NULL) {
        free(tmpPrv);
    }
}

static char *SDV_KAE_DH_SET_PUB_API_TC001_VEC[] = {
    "4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010",
};

static void SDV_KAE_DH_SET_PUB_API_TC001(void **state)
{
    const char *test = (const char *)*state;
    Hex *pubKey = NewHex();
    assert_int_equal(ConvertHex(test, pubKey), 0);

    CRYPT_EAL_PkeyPub pub = {0};
    Set_DH_Pub(&pub, pubKey->x, pubKey->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeySetPub(NULL, &pub), CRYPT_NULL_INPUT);

    pub.key.dhPub.data = NULL;
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_NULL_INPUT);

    pub.key.dhPub.data = pubKey->x;
    pub.key.dhPub.len = 0;
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_NULL_INPUT);

    FreeHex(pubKey);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static void SDV_KAE_DH_SET_PUB_API_TC002(void **state)
{
    (void)state;
    uint8_t pubKey[1025] = {0}; // 8192/8 + 1 = 1025
    uint32_t pubLen = sizeof(pubKey);
    pubKey[0] = 1;
    pubKey[1024] = 5; // 1024 is last block
    CRYPT_EAL_PkeyPub pub = {0};
    Set_DH_Pub(&pub, pubKey, pubLen);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_DH_KEYINFO_ERROR);

    pubKey[0] = 0;
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_DH_KEYINFO_ERROR);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_GET_PRV_API_TC001_VEC[] = {
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23",
        "1ea26e8b4b0061e1dccefb2f56b0dadd9d0fc297e215578823a07e97",
        NULL,
        NULL,
        NULL,
        NULL,
    },
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "",
        "1ea26e8b4b0061e1dccefb2f56b0dadd9d0fc297e215578823a07e97",
        NULL,
        NULL,
        NULL,
        NULL,
    },
};

static void SDV_KAE_DH_GET_PRV_API_TC001(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();
    Hex *prvKey = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);
    assert_int_equal(ConvertHex(test->prv1, prvKey), 0);

    uint8_t output[1030];
    uint32_t outLen = sizeof(output);
    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPrv prv = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);
    Set_DH_Prv(&prv, output, outLen);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_DH_KEYINFO_ERROR);

    prv.key.dhPrv.data = prvKey->x;
    prv.key.dhPrv.len = prvKey->len;
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS);

    prv.key.dhPrv.data = NULL;
    prv.key.dhPrv.len = outLen;
    assert_int_equal(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_NULL_INPUT);

    prv.key.dhPrv.data = output;
    prv.key.dhPrv.len = prvKey->len - 1;
    assert_int_equal(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_DH_BUFF_LEN_NOT_ENOUGH);

    prv.key.dhPrv.len = p->len > q->len ? p->len : q->len;
    assert_int_equal(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_SUCCESS);
    assert_int_equal(prv.key.dhPrv.len, prvKey->len);
    assert_int_equal(memcmp(output, prvKey->x, prvKey->len), 0);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);
    FreeHex(prvKey);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static char *SDV_KAE_DH_GET_PUB_API_TC001_VEC[] = {
    "4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010",
};

void SDV_KAE_DH_GET_PUB_API_TC001(void **state)
{
    const char *test = (const char *)*state;
    Hex *pubKey = NewHex();
    assert_int_equal(ConvertHex(test, pubKey), 0);

    uint8_t output[1030];
    uint32_t outLen = sizeof(output);
    CRYPT_EAL_PkeyPub pub = {0};
    Set_DH_Pub(&pub, output, outLen);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_DH_KEYINFO_ERROR);

    pub.key.dhPub.data = pubKey->x;
    pub.key.dhPub.len = pubKey->len;
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_SUCCESS);

    pub.key.dhPub.data = NULL;
    pub.key.dhPub.len = outLen;
    assert_int_equal(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_NULL_INPUT);

    pub.key.dhPub.data = output;
    pub.key.dhPub.len = pubKey->len - 1;
    assert_int_equal(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_DH_BUFF_LEN_NOT_ENOUGH);

    pub.key.dhPub.len = pubKey->len;
    assert_int_equal(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_SUCCESS);
    assert_int_equal(pub.key.dhPub.len, pubKey->len);
    assert_int_equal(memcmp(output, pubKey->x, pubKey->len), 0);

    FreeHex(pubKey);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestPara SDV_KAE_DH_GET_KEY_LEN_API_TC001_VEC[] = {
    {"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
     "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
     "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b"},
    {"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699",
     "34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940",
     "de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103"},
};

static void SDV_KAE_DH_GET_KEY_LEN_API_TC001(void **state)
{
    CRYPT_Dh_TestPara *test = (CRYPT_Dh_TestPara *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    CRYPT_EAL_PkeyPara para = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeyGetKeyLen(pkey), 0);
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGetKeyLen(pkey), p->len);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestPara SDV_KAE_DH_GEN_API_TC001_VEC[] = {
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23",
    },
};

static void SDV_KAE_DH_GEN_API_TC001(void **state)
{
    CRYPT_Dh_TestPara *test = (CRYPT_Dh_TestPara *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    CRYPT_EAL_PkeyPara para = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeyGen(NULL), CRYPT_NULL_INPUT);

    assert_int_equal(CRYPT_EAL_PkeyGen(pkey), CRYPT_DH_PARA_ERROR);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);

    CRYPT_EAL_RandDeinit();
    assert_int_equal(CRYPT_EAL_PkeyGen(pkey), CRYPT_BN_RAND_GEN_FAIL);

    assert_int_equal(RandInit(), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_RandDeinit();
    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static void SDV_KAE_DH_SET_PARA_BY_ID_API_TC001(void **state)
{
    (void)state;
    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    assert_int_equal(CRYPT_EAL_PkeySetParaById(NULL, CRYPT_DH_RFC3526_2048), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_PkeySetParaById(pkey, 100), CRYPT_EAL_ERR_NEW_PARA_FAIL);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
    ;
}

static CRYPT_Dh_Test SDV_KAE_DH_EXCH_API_TC001_VEC[] = {
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23",
        "6822bde050fcddf90ba8c398d6c973552be0f8f4b48c86dfdda2c187",
        "4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010",
        NULL,
        NULL,
        NULL,
    },
};

static void SDV_KAE_DH_EXCH_API_TC001(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();
    Hex *pubKey = NewHex();
    Hex *prvKey = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);
    assert_int_equal(ConvertHex(test->prv1, prvKey), 0);
    assert_int_equal(ConvertHex(test->pub1, pubKey), 0);

    uint8_t share[1030];
    uint32_t shareLen = sizeof(share);
    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPrv prv = {0};
    CRYPT_EAL_PkeyPub pub = {0};

    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);
    Set_DH_Prv(&prv, prvKey->x, prvKey->len);
    Set_DH_Pub(&pub, pubKey->x, pubKey->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share, &shareLen), CRYPT_DH_PARA_ERROR);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey1, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(NULL, pkey2, share, &shareLen), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, NULL, share, &shareLen), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, NULL, &shareLen), CRYPT_NULL_INPUT);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, (uint8_t *)share, NULL), CRYPT_NULL_INPUT);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);
    FreeHex(prvKey);
    FreeHex(pubKey);

    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_EXCH_API_TC002_VEC[] = {
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23",
        "6822bde050fcddf90ba8c398d6c973552be0f8f4b48c86dfdda2c187",
        "4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010",
        NULL,
        NULL,
        NULL,
    },
};

static void SDV_KAE_DH_EXCH_API_TC002(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();
    Hex *pubKey = NewHex();
    Hex *prvKey = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);
    assert_int_equal(ConvertHex(test->prv1, prvKey), 0);
    assert_int_equal(ConvertHex(test->pub1, pubKey), 0);

    uint8_t share[1030];
    uint32_t shareLen = sizeof(share);

    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPrv prv = {0};
    CRYPT_EAL_PkeyPub pub = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);
    Set_DH_Prv(&prv, prvKey->x, prvKey->len);
    Set_DH_Pub(&pub, pubKey->x, pubKey->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    CRYPT_EAL_PkeyCtx *pkey3 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey3);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey1, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey3, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share, &shareLen), CRYPT_DH_KEYINFO_ERROR);

    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey3, pkey2, share, &shareLen), CRYPT_DH_KEYINFO_ERROR);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);
    FreeHex(prvKey);
    FreeHex(pubKey);

    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_PkeyFreeCtx(pkey3);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_Test SDV_KAE_DH_EXCH_API_TC003_VEC[] = {
    {
        "92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73",
        "2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29",
        "b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23",
        "6822bde050fcddf90ba8c398d6c973552be0f8f4b48c86dfdda2c187",
        "4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010",
        NULL,
        NULL,
        NULL,
    },
};

static void SDV_KAE_DH_EXCH_API_TC003(void **state)
{
    CRYPT_Dh_Test *test = (CRYPT_Dh_Test *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();
    Hex *pubKey = NewHex();
    Hex *prvKey = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);
    assert_int_equal(ConvertHex(test->prv1, prvKey), 0);
    assert_int_equal(ConvertHex(test->pub1, pubKey), 0);

    uint8_t share[1030];
    uint32_t shareLen;
    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPrv prv = {0};
    CRYPT_EAL_PkeyPub pub = {0};

    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);
    Set_DH_Prv(&prv, prvKey->x, prvKey->len);
    Set_DH_Pub(&pub, pubKey->x, pubKey->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey1);

    CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey2);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey1, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS);

    shareLen = CRYPT_EAL_PkeyGetKeyLen(pkey1) - 1;

    assert_int_equal(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, (uint8_t *)share, &shareLen),
                     CRYPT_DH_BUFF_LEN_NOT_ENOUGH);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);
    FreeHex(prvKey);
    FreeHex(pubKey);

    CRYPT_EAL_PkeyFreeCtx(pkey1);
    CRYPT_EAL_PkeyFreeCtx(pkey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestPara SDV_KAE_DH_GET_PARA_API_TC001_VEC[] = {
    {
        "da3a8085d372437805de95b88b675122f575df976610c6a844de99f1df82a06848bf7a42f18895c97402e81118e01a00d0855d51922f434c022350861d58ddf60d65bc6941fc6064b147071a4c30426d82fc90d888f94990267c64beef8c304a4b2b26fb93724d6a9472fa16bc50c5b9b8b59afb62cfe9ea3ba042c73a6ade35",
        "a51883e9ac0539859df3d25c716437008bb4bd8ec4786eb4bc643299daef5e3e5af5863a6ac40a597b83a27583f6a658d408825105b16d31b6ed088fc623f648fd6d95e9cefcb0745763cddf564c87bcf4ba7928e74fd6a3080481f588d535e4c026b58a21e1e5ec412ff241b436043e29173f1dc6cb943c09742de989547288",
        "f2ca7621eb250aa5f22cef1907011295defc50a7",
    },
};

static void SDV_KAE_DH_GET_PARA_API_TC001(void **state)
{
    CRYPT_Dh_TestPara *test = (CRYPT_Dh_TestPara *)*state;

    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    uint8_t buf_p[1030] = {0};
    uint32_t bufLen = sizeof(buf_p);
    uint8_t buf_q[1030] = {0};
    uint8_t buf_g[1030] = {0};

    CRYPT_EAL_PkeyPara para = {0};
    CRYPT_EAL_PkeyPara para2 = {0};
    Set_DH_Para(&para, p->x, q->x, g->x, p->len, q->len, g->len);
    Set_DH_Para(&para2, buf_p, buf_q, buf_g, bufLen, bufLen, bufLen);
    para2.id = CRYPT_PKEY_RSA;

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pKey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pKey);

    assert_int_equal(CRYPT_EAL_PkeySetPara(pKey, &para), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyGetPara(pKey, &para2), CRYPT_EAL_ERR_ALGID);

    assert_int_equal(CRYPT_EAL_PkeyGetPara(NULL, &para2), CRYPT_NULL_INPUT);

    assert_int_equal(CRYPT_EAL_PkeyGetPara(pKey, NULL), CRYPT_NULL_INPUT);

    para2.id = CRYPT_PKEY_DH;
    assert_int_equal(CRYPT_EAL_PkeyGetPara(pKey, &para2), CRYPT_SUCCESS);
    assert_int_equal(para.para.dhPara.pLen, para2.para.dhPara.pLen);
    assert_int_equal(memcmp(para.para.dhPara.p, para2.para.dhPara.p, para.para.dhPara.pLen), 0);
    assert_int_equal(para.para.dhPara.qLen, para2.para.dhPara.qLen);
    assert_int_equal(memcmp(para.para.dhPara.q, para2.para.dhPara.q, para.para.dhPara.qLen), 0);
    assert_int_equal(para.para.dhPara.gLen, para2.para.dhPara.gLen);
    assert_int_equal(memcmp(para.para.dhPara.g, para2.para.dhPara.g, para.para.dhPara.gLen), 0);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_PkeyFreeCtx(pKey);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestCmp SDV_KAE_DH_CMP_API_TC001_VEC[] = {
    {
        CRYPT_DH_RFC7919_2048,
        "84ADA2846AA8E9E487AE91CA237249195A854A7F5ACD3DEBB72F53F37C0D69616B84DB55B2D1247D74F34132889D53C2F367D2C5FB025CA0EEDF5D57E9951831DF9D2A856F0D3F01B848FF90AE9563A09EBBA3E9E8607562BC498E15C30D2DB9849CB131B40F8823CEFE54E461F5E730B7BAE2BD59C3BE735F10300110F0B48F60B5E2EDDFBAC028C110070164DBE51C3FAB06E354CA84757B8A11B9AEF775C4676DDAC74FE119E28CCA1BF126C04D85A8406DE95AE18B38AFE6932B29B6AFB2E0E2699AD26BC8E65CC22E2B607A1FC2C5AF966F27FB71C67E024193F186C3A874AF68B0ABC70869DCB59550B5A0C9236E2A4712A836A486780EE7D53C4FB3F1",
    },
};

static void SDV_KAE_DH_CMP_API_TC001(void **state)
{
    CRYPT_Dh_TestCmp *test = (CRYPT_Dh_TestCmp *)*state;

    int32_t paraId = test->id;
    Hex *pubKey = NewHex();
    assert_int_equal(ConvertHex(test->key, pubKey), 0);

    CRYPT_EAL_PkeyPub pub = {0};
    Set_DH_Pub(&pub, pubKey->x, pubKey->len);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(ctx1);

    CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(ctx2);

    assert_int_equal(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_DH_KEYINFO_ERROR); // no key and no para

    assert_int_equal(CRYPT_EAL_PkeySetParaById(ctx1, paraId), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetPub(ctx1, &pub), CRYPT_SUCCESS);

    assert_int_equal(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_DH_KEYINFO_ERROR); // ctx2 no pubkey

    assert_int_equal(CRYPT_EAL_PkeySetPub(ctx2, &pub), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_DH_PARA_ERROR); // ctx2 no para

    FreeHex(pubKey);

    CRYPT_EAL_PkeyFreeCtx(ctx1);
    CRYPT_EAL_PkeyFreeCtx(ctx2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static void SDV_KAE_DH_CTRL_API_TC001(void **state)
{
    (void)state;
    int32_t ref = 1;
    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(ctx);

    assert_int_equal(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_PADDING, &ref, sizeof(int32_t)),
                     CRYPT_DH_UNSUPPORTED_CTRL_OPTION);

    CRYPT_EAL_PkeyFreeCtx(ctx);
    CRYPT_EAL_LibCtxFree(libctx);
}

static void SDV_KAE_DH_DUP_CTX_FUNC_TC001(void **state)
{
    (void)state;
    uint8_t *pubKey1 = NULL;
    uint8_t *pubKey2 = NULL;
    uint32_t keyLen1;
    uint32_t keyLen2;
    CRYPT_PKEY_ParaId paraId = CRYPT_DH_RFC7919_2048;
    CRYPT_EAL_PkeyPub pub = {0};
    CRYPT_EAL_PkeyCtx *ctx = NULL;
    CRYPT_EAL_PkeyCtx *dupCtx = NULL;

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    ctx = CRYPT_EAL_ProviderPkeyNewCtx(libctx, CRYPT_PKEY_DH,
                                       CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(ctx);

    assert_int_equal(RandInit(), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeySetParaById(ctx, paraId), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGen(ctx), CRYPT_SUCCESS);

    dupCtx = CRYPT_EAL_PkeyDupCtx(ctx);
    assert_non_null(dupCtx);

    assert_int_equal(CRYPT_EAL_PkeyCmp(ctx, dupCtx), CRYPT_SUCCESS);

    keyLen1 = CRYPT_EAL_PkeyGetKeyBits(ctx);
    keyLen2 = CRYPT_EAL_PkeyGetKeyBits(dupCtx);
    assert_int_equal(keyLen1, keyLen2);

    pubKey1 = calloc(1u, keyLen1);
    pubKey2 = calloc(1u, keyLen2);
    assert_non_null(pubKey1);
    assert_non_null(pubKey2);

    Set_DH_Pub(&pub, pubKey1, keyLen1);
    assert_int_equal(CRYPT_EAL_PkeyGetPub(ctx, &pub), CRYPT_SUCCESS);
    Set_DH_Pub(&pub, pubKey2, keyLen2);
    assert_int_equal(CRYPT_EAL_PkeyGetPub(dupCtx, &pub), CRYPT_SUCCESS);

    assert_memory_equal(pubKey1, pubKey2, keyLen2);
    assert_int_equal(CRYPT_EAL_PkeyGetParaId(dupCtx), paraId);

    CRYPT_EAL_RandDeinit();
    CRYPT_EAL_PkeyFreeCtx(ctx);
    CRYPT_EAL_PkeyFreeCtx(dupCtx);
    BSL_SAL_Free(pubKey1);
    BSL_SAL_Free(pubKey2);
    CRYPT_EAL_LibCtxFree(libctx);
}

static CRYPT_Dh_TestGetKeyBits SDV_KAE_DH_GET_KEY_BITS_FUNC_TC001_VEC[] = {
    {
        2048,
        "ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d",
        "aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff",
        "c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b",
    },
};

static void SDV_KAE_DH_GET_KEY_BITS_FUNC_TC001(void **state)
{
    CRYPT_Dh_TestGetKeyBits *test = (CRYPT_Dh_TestGetKeyBits *)*state;

    int32_t keyBits = test->keyBits;
    Hex *p = NewHex();
    Hex *g = NewHex();
    Hex *q = NewHex();

    assert_int_equal(ConvertHex(test->p, p), 0);
    assert_int_equal(ConvertHex(test->g, g), 0);
    assert_int_equal(ConvertHex(test->q, q), 0);

    CRYPT_EAL_LibCtx *libctx = CreateLoadLibCtx();
    CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_ProviderPkeyNewCtx(
        libctx, CRYPT_PKEY_DH, CRYPT_EAL_PKEY_KEYMGMT_OPERATE + CRYPT_EAL_PKEY_EXCH_OPERATE, "provider=kaev1");
    assert_non_null(pkey);

    CRYPT_EAL_PkeyPara para;
    para.id = CRYPT_PKEY_DH;
    para.para.dhPara.p = p->x;
    para.para.dhPara.pLen = p->len;
    para.para.dhPara.q = q->x;
    para.para.dhPara.qLen = q->len;
    para.para.dhPara.g = g->x;
    para.para.dhPara.gLen = g->len;

    assert_int_equal(CRYPT_EAL_PkeySetPara(pkey, &para), CRYPT_SUCCESS);
    assert_int_equal(CRYPT_EAL_PkeyGetKeyBits(pkey), (uint32_t)keyBits);

    FreeHex(p);
    FreeHex(g);
    FreeHex(q);

    CRYPT_EAL_PkeyFreeCtx(pkey);
    CRYPT_EAL_LibCtxFree(libctx);
}

int main()
{
    struct CMUnitTest tests[GROUP_TEST_MAX] = {NULL};
    int testCnt = 0;

    tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test(SDV_KAE_DH_PROVIDER_LOAD);
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_FUNC_TC001_VEC) / sizeof(SDV_KAE_DH_FUNC_TC001_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_FUNC_TC001, &SDV_KAE_DH_FUNC_TC001_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_FUNC_TC002_VEC) / sizeof(SDV_KAE_DH_FUNC_TC002_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_FUNC_TC002, &SDV_KAE_DH_FUNC_TC002_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_FUNC_TC003_VEC) / sizeof(SDV_KAE_DH_FUNC_TC003_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_FUNC_TC003, &SDV_KAE_DH_FUNC_TC003_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_FUNC_TC004_VEC) / sizeof(SDV_KAE_DH_FUNC_TC004_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_FUNC_TC004, &SDV_KAE_DH_FUNC_TC004_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_FUNC_TC005_VEC) / sizeof(SDV_KAE_DH_FUNC_TC005_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_FUNC_TC005, &SDV_KAE_DH_FUNC_TC005_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_FUNC_TC006_VEC) / sizeof(SDV_KAE_DH_FUNC_TC006_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_FUNC_TC006, &SDV_KAE_DH_FUNC_TC006_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_SET_PARA_API_TC001_VEC) / sizeof(SDV_KAE_DH_SET_PARA_API_TC001_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_SET_PARA_API_TC001,
                                                                        &SDV_KAE_DH_SET_PARA_API_TC001_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_SET_PARA_API_TC002_VEC) / sizeof(SDV_KAE_DH_SET_PARA_API_TC002_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_SET_PARA_API_TC002,
                                                                        &SDV_KAE_DH_SET_PARA_API_TC002_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_SET_PARA_API_TC003_VEC) / sizeof(SDV_KAE_DH_SET_PARA_API_TC003_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_SET_PARA_API_TC003,
                                                                        &SDV_KAE_DH_SET_PARA_API_TC003_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_SET_PARA_API_TC004_VEC) / sizeof(SDV_KAE_DH_SET_PARA_API_TC004_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_SET_PARA_API_TC004,
                                                                        &SDV_KAE_DH_SET_PARA_API_TC004_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_SET_PRV_API_TC001_VEC) / sizeof(SDV_KAE_DH_SET_PRV_API_TC001_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_SET_PRV_API_TC001,
                                                                        &SDV_KAE_DH_SET_PRV_API_TC001_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_SET_PRV_API_TC002_VEC) / sizeof(SDV_KAE_DH_SET_PRV_API_TC002_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_SET_PRV_API_TC002,
                                                                        &SDV_KAE_DH_SET_PRV_API_TC002_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_SET_PUB_API_TC001_VEC) / sizeof(SDV_KAE_DH_SET_PUB_API_TC001_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_SET_PUB_API_TC001,
                                                                        SDV_KAE_DH_SET_PUB_API_TC001_VEC[i]);
    }
    tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test(SDV_KAE_DH_SET_PUB_API_TC002);
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_GET_PRV_API_TC001_VEC) / sizeof(SDV_KAE_DH_GET_PRV_API_TC001_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_GET_PRV_API_TC001,
                                                                        &SDV_KAE_DH_GET_PRV_API_TC001_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_GET_PUB_API_TC001_VEC) / sizeof(SDV_KAE_DH_GET_PUB_API_TC001_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_GET_PUB_API_TC001,
                                                                        SDV_KAE_DH_GET_PUB_API_TC001_VEC[i]);
    }
    for (size_t i = 0;
         i < sizeof(SDV_KAE_DH_GET_KEY_LEN_API_TC001_VEC) / sizeof(SDV_KAE_DH_GET_KEY_LEN_API_TC001_VEC[0]); i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_GET_KEY_LEN_API_TC001,
                                                                        &SDV_KAE_DH_GET_KEY_LEN_API_TC001_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_GEN_API_TC001_VEC) / sizeof(SDV_KAE_DH_GEN_API_TC001_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_GEN_API_TC001, &SDV_KAE_DH_GEN_API_TC001_VEC[i]);
    }
    tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test(SDV_KAE_DH_SET_PARA_BY_ID_API_TC001);
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_EXCH_API_TC001_VEC) / sizeof(SDV_KAE_DH_EXCH_API_TC001_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_EXCH_API_TC001, &SDV_KAE_DH_EXCH_API_TC001_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_EXCH_API_TC002_VEC) / sizeof(SDV_KAE_DH_EXCH_API_TC002_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_EXCH_API_TC002, &SDV_KAE_DH_EXCH_API_TC002_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_EXCH_API_TC003_VEC) / sizeof(SDV_KAE_DH_EXCH_API_TC003_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_EXCH_API_TC003, &SDV_KAE_DH_EXCH_API_TC003_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_GET_PARA_API_TC001_VEC) / sizeof(SDV_KAE_DH_GET_PARA_API_TC001_VEC[0]);
         i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_GET_PARA_API_TC001,
                                                                        &SDV_KAE_DH_GET_PARA_API_TC001_VEC[i]);
    }
    for (size_t i = 0; i < sizeof(SDV_KAE_DH_CMP_API_TC001_VEC) / sizeof(SDV_KAE_DH_CMP_API_TC001_VEC[0]); i++) {
        tests[testCnt++] =
            (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_CMP_API_TC001, &SDV_KAE_DH_CMP_API_TC001_VEC[i]);
    }
    tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test(SDV_KAE_DH_CTRL_API_TC001);
    tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test(SDV_KAE_DH_DUP_CTX_FUNC_TC001);
    for (size_t i = 0;
         i < sizeof(SDV_KAE_DH_GET_KEY_BITS_FUNC_TC001_VEC) / sizeof(SDV_KAE_DH_GET_KEY_BITS_FUNC_TC001_VEC[0]); i++) {
        tests[testCnt++] = (struct CMUnitTest)cmocka_unit_test_prestate(SDV_KAE_DH_GET_KEY_BITS_FUNC_TC001,
                                                                        &SDV_KAE_DH_GET_KEY_BITS_FUNC_TC001_VEC[i]);
    }
    cmocka_run_group_tests(tests, NULL, NULL);
    return 0;
}
